archlinux-支持iphone插线3G

度娘永远都不会告诉你真正的答案是什么。

因为没有了CMCC-EDU,用上了坑爹联通,所以现在习惯于手机USB上网了。。(博主套餐流量看个技术是可以的。。)

然后问题就来了。。CentOS7上可以安稳的使用3G但是arch似乎不支持,百度了好久也没有找到。

后来bing 了一下iphone arch linux神奇的wiki就出来了,随后就申请了个帐号,准备在学习Linux的过程中学习英语。给wiki

做点翻译还是可以的吧= =。

方法很简单, 因为我用的是NetworkManager, 所以最简单而行之有效的方法是:

pacman -S libimobiledevice
pacman -S usbmuxd  ifuse

重启机器或者NetworkManager搞定。

虽然无关技术以及学术痛痒,但是总感觉在Linux普及上尽了一份力= =

archlinux-安装笔记

  • 本文出自<svtter.github.io>

花了一些时间安装arch,记录一下注意事项。

多重引导

  • 安装多重引导支持

    pacman -S os-prober

  • 更新grub

    grub-mkconfig -o /boot/grub/grub.cfg

  • 写入mbr

    grub-install --target=i386-pc --recheck /dev/sda

图形化的网络服务

systemctl enable NetWorkManager.service

wifi配置

  • 如果你想使用wifi(在图形界面下),首先你要停止dhcp服务systemctl stop dhcpcd.service
  • 开机停止运行systemctl disable dhcpcd.service
  • 我们之所以这样,是为了保证我们的NetWorkManager正常服务。

session控制器

我选择的是gdm,原因是slim我不太会配置。

pacman -S gdm

另外patheon在我书写这篇blog的时候,还是存在不少bug.官方的wiki在这个时候也不是很好用了。期待patheon!

添加了官方给的patheon库,会出现一个gnome-lib的冲突

输入法的注意事项

使用fcitx需要注意.xprofile的配置问题。

export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"

其他的安装情况可以看看官方的wiki

sudoer的配置

使用pacman安装sudoer

pacman -S sudo

编辑/etc/sudoers,取消wheel用户组的注释.

vim配置

gvim中,直接使用synatic on而不用判断,否则会造成代码高亮失效。

locate配置

安装以后发现locate命令无法使用,安装pacman -S mlocate

另外, mark一个项目:gitbook, 很好很强大

应该涵盖了所有的我安装时候遇到的问题,如果还有什么问题,我再后续添加。

Linux-进程间的通信

  • 本文出自<svtter.github.io>

实验内容

消息的创建,发送,和接收。

<任务>

使用系统调用 msgget( ), megsnd( ), msgrev( )及 msgctl()编制一长度为 1K 的消息发送和接收的程序 。

程序设计

  1. 为了便于操作和观察结, 用一个程序为引子 , 先后fork( )两个子进程 , SERVER 和 CLIENT,进行通信。
  2. SERVER 端建立一个 Key 为 75 的消息队列,等待其他进程发来的消息。当遇到类型为 1 的消息,
则作为结束信号,取消该队列,并退出 SERVER 。SERVER 每接收到一个消息后显示一句 “(server)received”。
  1. CLIENT 端使用 Key 为 75 的消息队列,先后发送类型从 10 到 1 的消息,然后退出。最后的一个
消息,既是 SERVER 端需要的结束信号。CLIENT 每发送一条消息后显示一句“(client)sent”。
  1. 父进程在 SERVER 和 CLIENT 均退出后结束。

使用的函数

并非每次创建消息队列都会成功,所以重新添加-1情况的判断。

可以使用ipcs -q命令查看

源代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#define MSGKEY 75
struct msgform
{
    long mtype;
    char mtexe[100];
}msg;
int msgqid, i;
void CLIENT()
{
    int i;
    msgqid = msgget(MSGKEY, 0777|IPC_CREAT);
    if( msgqid == -1)
    {
        puts("client error in build");
        return;
    }
    else
        printf("client qid is: %d\n", msgqid);
    for (i = 10; i >= 1; i --)
    {
        msg.mtype = i;
        printf("(client)sent mtype %ld.\n", msg.mtype);
        msgsnd(msgqid, &msg, strlen(msg.mtexe)+1, );
    }
    puts("client exit...");
    exit();
}
void SERVER()
{
    msgqid = msgget(MSGKEY, 0777|IPC_CREAT);
    if( msgqid == -1)
    {
        printf("error in build.\n");
        return;
    }
    else
        printf("server qid is: %d\n", msgqid);
    do
    {
        msgrcv(msgqid, &msg, 1030, , );
        printf("(server)received mtype %ld.\n", msg.mtype);
    } while (msg.mtype != 1);
    msgctl(msgqid, IPC_RMID, );
    puts("server exit...");
}
int main ()
{
    if(fork())
    {
        SERVER();
        wait();
    }
    else
        CLIENT();
    return ;
}

运行结果

进程间的通信

Linux-管道

  • 本文出自<svtter.github.io>

  • 头文件: #include<unistd.h>

  • 使用方法: int pipe(int chan[2]);

  • 说明: pipe会建立管道,并将文件描述词通过chan返回。一般chan[0]为管道的读取端,chan[1]是写入端。

  • 返回值: 成功返回0,失败返回-1,错误信息保存在errno中

  • 错误信息:

    • EMFILE 进程已用完文件描述词最大量。
    • ENFILE 系统已无文件描述词可用。
    • EFAULT 参数filedes数组地址不合法
/*=============================================================================
#
# Author: svtter - [email protected]
#
# QQ : 57180160
#
# Last modified: 2014-11-21 16:20
#
# Filename: 管道.c
#
# Description: 
#
=============================================================================*/
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
char parent[] = "a message from parent";
char child[] = "a message from child";
int main ()
{
    int p2c[2], c2p[2];
    int pid;
    char buf[100];
    pipe(p2c);
    pipe(c2p);
    pid = fork();
    if(pid > )
    {
        close(c2p[]);
        close(p2c[1]);
        write(c2p[1], parent, sizeof(parent));
        close(c2p[1]);
        read(p2c[], buf, 100);
        printf("%s\n", buf);
        close(p2c[]);
    }
    else if(pid == )
    {
        close(p2c[]);
        close(c2p[1]);
        read(c2p[], buf, 100);
        printf("%s\n", buf);
        write(p2c[1], child, sizeof(child));
        close(c2p[]);
        close(p2c[]);
    }
    return ;
}

运行结果:

管道运行结果

Linux-同步互斥

  • 本文出自<svtter.github.io>

使用pthread实现经典问题:生产者消费者

关于semaphore的相关信息就不再贴出来了。

编译的时候记得-pthread选项。

/*=============================================================================
#
# Author: svtter - [email protected]
#
# QQ : 57180160
#
# Last modified: 2014-10-03 20:35
#
# Filename: producer_consumer.cc
#
# Description: 
#
=============================================================================*/
#include <cstdio>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define N 5
#define item int
// P/V操作
void P(sem_t* sem)
{
    if(sem_wait(sem))
        perror("P error!");
}
void V(sem_t* sem)
{
    if(sem_post(sem))
        perror("V error!");
}
sem_t mutex;
sem_t full;
sem_t empty;
item buffer[N];
int i = , j = -1;
void init_sem()
{
    sem_init(&mutex, , 1);
    sem_init(&full, , );
    sem_init(&empty, , N);
}
void* producer(void *arg)
{
    int product;
    while(1)
    {
        //生成随机数字
        product = rand()%100;
        // cout << "producer running..." << endl;
        P(&empty);
        P(&mutex);
        buffer[i] = product;
        printf("producer produced %d @ %d pos\n",
                product, i);
        i=(i+1)%N;
        V(&mutex);
        V(&full);
        sleep(1);
    }
}
void* consumer(void *arg)
{
    int product, temp;
    while(1)
    {
        // cout << "consumer running..." << endl;
        P(&full);
        P(&mutex);
        j = (j+1)%N;
        product = buffer[j];
        V(&mutex);
        V(&empty);
        printf("Consumer consumed %d @ %d pos\n",
                product, j);
        sleep(3);
    }
}
int main()
{
    //random num
    srand(time(NULL));
    init_sem();
    int error;
    pthread_t producer_t, consumer_t;
    error = pthread_create(&producer_t, NULL, producer, NULL);
    if(error != )
        printf("error in create producer.\n");
    else
        printf("create producer success!\n");
    pthread_create(&consumer_t, NULL, consumer, NULL);
    if(error != )
        printf("error in create consumer.\n");
    else
        printf("create consumer success!\n");
    pthread_join(producer_t, NULL);
    pthread_join(consumer_t, NULL);
    return ;
}

运行结果

生产者消费者

操作系统经典问题:哲学家就餐问题

mutex是c++11的新功能。记得添加C++11支持。(在运行结果中包含编译选项。)

#include <iostream>
#include <mutex>
#include <cstdio>
#include <thread>
#include <semaphore.h>
using namespace std;
#define THINK(i) printf("ph[%d] is thinking...\n", i)
#define EAT(i) printf("ph[%d] eats.\n", i)
void P(mutex &mt)
{
    mt.lock();
}
void V(mutex &mt)
{
    mt.unlock();
}
void P(sem_t* sem)
{
    if(sem_wait(sem))
        perror("P error!");
}
void V(sem_t* sem)
{
    if(sem_post(sem))
        perror("V error!");
}
// 加入unistd.h出现问题,似乎与thread的兼容性比较差,于是重写
void delay()
{
    int sum=;
    for(int i = ; i < 10000000; i++)
        sum += i;
}
mutex fork[5];
sem_t room;
void init()
{
    sem_init(&room, , 4);
}
void philosopher (int i)
{
    for(int j = ; j < 5; j++)
    {
        THINK(i);
        P(&room);
        P(fork[i]);
        P(fork[(i+1)%5]);
        EAT(i);
        V(&room);
        V(fork[i]);
        V(fork[(i+1)%5]);
    }
}
int main()
{
    init();
    thread t[] = {
        thread(philosopher, ),
        thread(philosopher, 1),
        thread(philosopher, 2),
        thread(philosopher, 3),
        thread(philosopher, 4),
    };
    for(int k = ; k < 5; k++)
        t[k].join();
    return ;
}

运行结果

哲学家就餐

操作系统经典问题:读者写者问题

读者优先

  • 使用了c++11的新特性thread
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex mt, wsem;
int readcount = ;
#define READ(a) cout << a << " is reading..." << endl;
#define FINISH(a) cout << a << " finished reading." << endl;
#define WRITE cout << "writing..." << endl;
void P(mutex &mt)
{
    mt.lock();
}
void V(mutex &mt)
{
    mt.unlock();
}
// 加入unistd.h出现问题,似乎与thread的兼容性比较差,于是重写
void delay()
{
    int sum=;
    for(int i = ; i < 10000000; i++)
        sum += i
}
void read(string a)
{
    for(int i = ; i < 3; i++)
    {
        P(mt);
        readcount++;
        if(readcount == 1)
            P(wsem);
        V(mt);
        READ(a);
        delay();
        P(mt);
        readcount--;
        FINISH(a);
        if(readcount == )
            V(wsem);
        V(mt);
    }
}
void write()
{
    for(int i = ; i < 5; i++)
    {
        P(wsem);
        WRITE;
        delay();
        V(wsem);
    }
}
int main()
{
    thread reader1(read, "svtter");
    thread reader2(read, "sr");
    thread reader3(read, "yym");
    thread reader4(read, "xiaoniu");
    thread writer(write);
    reader1.join();
    reader2.join();
    reader3.join();
    reader4.join();
    writer.join();
    return ;
}

运行结果

由于可以同时阅读,所以读者reading输出可能出现少许问题。

[阅读全文]
cpp 

Linux系统函数简介

本文出自<svtter.github.io>

系统调用函数说明、参数值及定义

本文摘自老师的资料= =

使用这些函数的时候记得将头文件unistd.h包含到程序中

1、fork()

创建一个新进程

int fork()

其中返回int取值意义如下:

0:创建子进程,从子进程返回的id值大于0:从父进程返回的子进程id值 -1:创建失败

2、lockf(files,function,size):

用作锁定文件的某些段或者整个文件,本函数适用的头文件为:

#include<unistd.h>

参数定义:

int lockf(files,function,size)

int files,function;

long size;

其中:files是文件描述符:function是锁定和解锁;1表示锁定,0表示解锁。size是锁定和解锁的字节数,若用0,表示从文件的当前位置到文件尾。

3、msgget(key,flag):

获得一个消息的描述符,该描述符指定一个消息队列以便用于其他系统调用。

该函数使用偷文件如下:

#include<sy/types.h>

#include<sy/ipc.h>

#include<sy/msg.h>

参数定义

int msgget(key,flag)

key_tkey;

int flag;

语法格式:msgqid=msgget(key,flag)

其中:msgid是该系统调用返回的描述符,失败则返回-1;flag 本身由操作允许权和控制命令值相或得到。

如:

IP_CREAT|0400 是否该队列应被创建;

IP_EXCL |0400 是否该队列的创建应是互斥的;等。

msgsnd(id,msgp,size,flag):

发送一消息。

该函数是用头文件如下:

#include<sy/types.h>

#include<sy/ipc.h>

#include<sy/msg.h>

参数定义

int msgnd(id,msgp,size,flag)

int id,size,flag;

struct msgbuf * msgp;

其中:id是返回消息队列的描述符;msgp是指向用户存储区的一个构造体指针,size指示由msgp

指向的数据结构中字符数组的长度;即消息的长度。这个数组的最大值由MSG-MAX系统可调用参数来确

定。flag规定当核心用尽内部缓冲空间时应执行的动作;若在标志flag中末设置IPC_NOWAIT位,则当

41该消息队列中字节数超过一最大值时,或系统范围的消息数超过某一最大值时,调用msgsnd进程睡眠。

若是设置IPC_NOWAIT,则在此情况下,msgsnd立即返回。

msgrcv(id,msgp,size,type,flag):

接受一消息。

该函数调用使用头文件如下:

#include<sy/types.h>

#include<sy/ipc.h>

#include<sy/msg.h>

参数定义

[阅读全文]

解决无法在CentOS下的gvim中使用ibus输入中文

问题

之前在gvim中一直无法使用中文,格外痛苦,后来使用了vim-ibus插件之后,可以在vim中使用中文了,但是依然不能在gvim中使用,一直以为是两个软件冲突的

问题,现在终于解决了。

  • gvim version: vim-X11
  • ibus version: 1.6

解决方案

  • 问题出在:使用的vim插件中有插件与ibus冲突,但是奈何找不到X11的log(应该可以找到,找到再说。。)
  • 排查方式比较简单,使用:PluginInstall,:PluginClean即可(考虑到我使用vundle管理插件)
  • 去除相应的插件即可(比如现在冲突的是auto-pairs)。如果不想去除冲突插件,可以考虑使用vim-ibus,这个在shell下是可以使得很多冲突减少的。
  • 可能auto-pairs在不久的将来就会修复这个bug,请在具体环境下排查
vim  Linux  CentOS 

Linux-存储管理

还未动笔

Linux-进程管理

本文出自<svtter.github.io>

进程的创建

用于进程的创建。fork()的作用是,从当前位置创建一个子进程,并执行。fork的返回值为子进程的pid

#include <stdio.h>
void main()
{
    int p1, p2;
    if (p1 = fork()) //父进程返回1, 子进程返回0
        putchar('b');
    else
    {
        if(p2 = fork())
            putchar('c');
        else
            putchar('a');
    }
}

运行结果

运行结果

进程的控制

在这段代码中使用了lockf, 和wait函数。作用是什么呢?

  • lockf顾名思义是锁定file. lockf(1, 1, 0)锁定资源,lockf(1, 0, 0)释放资源。

  • wait作用为等待子进程的返回信息。wait中的signal用于接受进程的返回信号,即exit(0)中的0

#include <stdio.h>
#include <wait.h>
// 利用lockf(1, 1, 0)锁定输出设备
// lockf(1, 0, 0)解锁输出设备
int main()
{
    int p1, p2, i;
    if(p1 = fork())
    {
        lockf(1, 1, );
        for(i = ; i < 500; i++)
            printf("parent%d\n", i);
        lockf(1, , );
        wait();        //confirm the father killed after child
        exit();
    }
    else
    {
        if(p2 = fork())
        {
            lockf(1, 1, );
            for(i = ; i < 500; i++)
            printf("son %d\n", i);
            lockf(1, , );
            wait();        //
            exit();
        }
        else
        {
            lockf(1, 1,);
            for(i = ; i < 500; i++)
                printf("grandchild%d\n", i);
            lockf(1, ,);
            exit();
        }
    }
}

运行结果

运行结果

Linux -基础学习笔记-2

Linux用户和用户组

  • 简单解释:
文件权限 连接数 文件所有者 文件所属用户组 文件大小 文件最后被修改的时间 文件名
-rw-r–r– 1 root root 42304 Sep 4 18:26 install.log
[阅读全文]