当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > 进程间通信原理
进程间通信原理
时间:2016-12-14作者:华清远见

同一台电脑下进程间通信方式有无名管道(pipe)、有名管道(fifo)、信号(signal)、共享内存(shm)、消息队列(msq)和信号灯(sem),要灵活的使用它们,就要知道它们的通信原理。

无名管道的原理是把无名管道当成文件,父进程创建(pipe)这个文件(无名管道),但这个文件在文件系统中不可见,它在内存中,所以只能通过子进程继承父进程的文件描述符(fd)来完成通信,这样无名管道只能用于父子进程间通信(有亲缘关系的进程间)。

具体实现如下:

int fd[2];
        pipe(fd);

有名管道的原理是把有名管道当成文件,任意进程创建(mkfifo)这个文件(有名管道),这个文件在文件系统中可见,但内容在内存中,既然文件系统可见,那么任意进程就可以通过open来打来这个文件进行读写(read、write),这样有名管道能用于任意进程间通信。

具体实现如下:

int fd;
        mkfifo(``fifo``, 0666)
        fd = open(``fifo``, O_RDONLY);

信号的原理是通过进程的pid进行通信,是软件中唯一的异步通信机制,它的关键是知道进程的pid。

具体实现如下:

kill(pid, sig);

共享内存、消息队列和信号灯是System V IPC对象,它们的通信原理都一样,是通过相同的key值生成相同的shmid、msgid和semid来实现任意进程间通信,那么它的关键是任意进程怎么知道这个key值,我们有个函数ftok能实现这个功能,它通过两个参数来生成key,任意进程只要这两个参数相同就能生成相同的key值,这样就能找到相同的IPC对象,实现任意进程间通信,这两个参数第一个必须是系统中现有的唯一id,比如目录的id和文件的id等,第二个参数是一个任意整数,这两个参数通过特定的计算可以生成唯一的key值。上面是任意进程间通信,还有一种是只有亲缘关系(父子进程)间通信时,key值没有必要用ftok来生成,我们有一个系统定义的参数IPC_PRIVATE可以实现父子进程间通信,这时的key值是0,当然父子进程间也可以用ftok,但这样就比较麻烦了。

具体实现如下:

// 任意进程间通信
        key_t key;
        int shmid;
        int msgid;
        int semid;

        key = ftok(``.``, `*`);
        // ``.``为当前目录,`*`为ascii码值42。

        shmid = shmget(key, ......);
        msgid = msgget(key, ......);
        semid = semget(key, ......);

        // 父子进程间通信

        int shmid;
        int msgid;
        int semid;

        shmid = shmget(IPC_PRIVATE, ......);
        msgid = msgget(IPC_PRIVATE, ......);
        semid = semget(IPC_PRIVATE, ......);

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)