Linux进程通信机制原理详解及实现步骤

来源:互联网 发布:移动网络摄像头 编辑:程序博客网 时间:2024/06/04 18:48

管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

一个进程写入管道的所有数据都由内核定向到另外一个进程,另外一个进程由此就可以从管道中读取数据。

创建一个管道的步骤:

1.调用get_pipe_inode()函数,在pipefs文件系统中为管道分配一个新的索引节点对象,并对其进行初始化。

2.为管道的读通道分配一个文件对象和一个文件描述符,并把这个文件对象的f_flag字段设置为O_RDONLY。

3.为管道的写通道分配一个文件对象和一个文件描述符,并把这个文件对象的f_flag字段设置为O_WRONLY。

4.分配一个目录项对象,并使用它把两个文件对象和索引节点对象连接在一起,然后,吧新的索引节点插入pipefs特殊文件系统中。

5.把两个文件描述符返回给用户态进程。

虽然管道是一种十分简单、灵活、有效的通信机制,但是他有一个主要的缺点,就是无法打开已经存在的管道。这使得任意两个进程不可能共享同一个管道,除非管道是由一个共同的祖先进程所创建。

 

FIFO:与管道几乎相同,主要有以下两点差别:

1.FIFO索引节点出现在系统的目录树上,而不是pipefs特殊的文件系统中。

2.FIFO是一种双向的通信管道,也就是说,可能以读/写模式打开一个FIFO。

 

信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。


消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。


信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。


共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

共享内存创建步骤:

1.调用int shmget( key_t key, size_t size, int flag )来获取一个共享内存区的IPC标识符,如果这个共享内存区不存在,就创建它。

2.调用void *shmat( int shm_id, const void *addr, int flag )把一个共享内存区“附加(attach)”到一个进程的地址空间(线性空间)中,但是并不修改该进程的页表。进程访问该内存区域是通过shm特殊文件系统映射到页高速缓存中进行获取数据页。

3.调用int shmctl( int shm_id, int cmd, struct shmid_ds *buf )可以操作该共享内存区的一些熟悉。

4.调用int shmdt( void *addr)来“分离”指定的共享内存区,也就是说把相应的共享内存区域从进程的地址空间中删除。IPC共享内存资源是持久的,即时现在没有进程在使用它,相应的页也不会被丢弃,但是可以被换出。

 

套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

原创粉丝点击