linux下的进程通讯手法基本上是从Unix平台上的进程通讯手法承继而来的。而对Unix开展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通讯方面的侧重点有所不同。前者对Unix前期的进程间通讯手法进行了体系的改善和扩大,形成了“system V IPC”,通讯进程约束在单个核算机内;后者则跳过了该约束,形成了根据套接口(socket)的进程间通讯机制。Linux则把两者承继了下来,如图示:
其间,开端Unix IPC包含:管道、FIFO、信号;System V IPC包含:System V音讯行列、System V信号灯、System V同享内存区;Posix IPC包含:Posix音讯行列、Posix信号灯、Posix同享内存区。有两点需求简略阐明一下:
1)由于Unix版别的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix规范,这个新的ANSI Unix规范被称为核算肪车目梢浦残圆僮飨低辰缑妫≒SOIX)。现有大部分Unix和盛行版别都是遵从POSIX规范的,而Linux从一开端就遵从 POSIX规范;
2)BSD并不是没有进入单机内的进程间通讯(socket本身就能够用于单机内的进程间通讯)。事实上,许多Unix版别的单机IPC留有BSD的痕迹,如4.4BSD支撑的匿名内存映射、4.3+BSD对牢靠信号语义的完成等等。
linux下进程间通讯的几种首要手法简介:
1.管道
管道是进程间通讯中最陈旧的方法,它包含无名管道和有名管道两种,前者可用于具有亲缘联系进程间的通讯,即可用于父进程和子进程间的通讯,后者额克服了管道没有姓名的约束,因而,除具有前者所具有的功用外,它还答应无亲缘联系进程间的通讯,即可用于运转于同一台机器上的恣意两个进程间的通讯。
无名管道由pipe()函数创立:
#include
int pipe(int filedis);
参数filedis回来两个文件描述符:filedes[0]为读而翻开,filedes为写而翻开。filedes的输出是filedes[0]的输入。
在Linux体系下,有名管道可由两种方法创立:命令行方法mknod体系调用和函数mkfifo。下面的两种途径都在当时目录下生成了一个名为myfifo的有名管道:
方法一:mkfifo("myfifo","rw");
方法二:mknod myfifo p
生成了有名管道后,就能够运用一般的文件I/O函数如open、close、read、write等来对它进行操作。
2.音讯行列
音讯行列是音讯的链接表,包含Posix音讯行列system V音讯行列。音讯行列用于运转于同一台机器上的进程间通讯,它和管道很相似,有满足权限的进程能够向行列中增加音讯,被赋予读权限的进程则能够读走行列中的音讯。音讯行列克服了信号承载信息量少,管道只能承载无格局字节省以及缓冲区巨细受限等缺陷。
咱们能够用流管道或许套接口的方法来替代它。
3.同享内存
同享内存是运转在同一台机器上的进程间通讯最快的方法,由于数据不需求在不同的进程间仿制。一般由一个进程创立一块同享内存区,其他进程对这块内存区进行读写。同享内存往往与其它通讯机制,如信号量结合运用,来到达进程间的同步及互斥。
首要要用的函数是shmget,它取得一个同享存储标识符。
#include
#include
#include
int shmget(key_t key, int size, int flag);
这个函数有点相似咱们了解的malloc函数,体系依照恳求分配size巨细的内存用作同享内存。linux体系内核中每个IPC结构都有的一个非负整数的标识符,这样对一个音讯行列发送音讯时只需引证标识符就能够了。这个标识符是内核由IPC结构的关键字得到的,这个关键字,便是上面第一个函数的key。数据类型key_t是在头文件sys/types.h中界说的,它是一个长整形的数据。在咱们后边的章节中,还会碰到这个关键字。
当同享内存创立后,其他进程能够调用shmat()将其衔接到本身的地址空间中。
void *shmat(int shmid, void *addr, int flag);
shmid为shmget函数回来的同享存储标识符,addr和flag参数决议了以什么方法来确认衔接的地址,函数的回来值便是该进程数据段所衔接的实践地址,进程能够对此进程进行读写操作。
运用同享存储来完成进程间通讯的留意点是对数据存取的同步,有必要保证当一个进程去读取数据时,它所想要的数据现已写好了。一般,信号量被要来完成对同享存储数据存取的同步,别的,能够经过运用shmctl函数设置同享存储内存的某些标志位如SHM_LOCK、SHM_UNLOCK等来完成。
4. 信号量
信号量又称为信号灯,它是用来和谐不同进程间的数据目标的,而最首要的应用是前一节的同享内存方法的进程间通讯。本质上,信号量是一个计数器,它用来记载对某个资源(如同享内存)的存取情况。一般说来,为了取得同享资源,进程需求履行下列操作:
(1) 测验操控该资源的信号量。
(2) 若此信号量的值为正,则答应进行运用该资源。进程将进号量减1。
(3) 若此信号量为0,则该资源现在不可用,进程进入睡觉状况,直至信号量值大于0,进程被唤醒,转入过程(1)。
(4) 当进程不再运用一个信号量操控的资源时,信号量值加1。假如此刻有进程正在睡觉等候此信号量,则唤醒此进程。
保护信号量状况的是Linux内核操作体系而不是用户进程。咱们能够从头文件/usr/src/linux/include/linux /sem.h中看到内核用来保护信号量状况的各个结构的界说。信号量是一个数据调集,用户能够独自运用这一调集的每个元素。要调用的第一个函数是 semget,用以取得一个信号量ID。
#include
#include
#include
int semget(key_t key, int nsems, int flag);
key是前面讲过的IPC结构的关键字,它将来决议是创立新的信号量调集,仍是引证一个现有的信号量调集。nsems是该调集中的信号量数。假如是创立新调集(一般在服务器中),则有必要指定nsems;假如是引证一个现有的信号量调集(一般在客户机中)则将nsems指定为0。
semctl函数用来对信号量进行操作。
int semctl(int semid, int semnum, int cmd, union semun arg);
不同的操作是经过cmd参数来完成的,在头文件sem.h中界说了7种不同的操作,实践编程时能够参照运用。
semop函数主动履行信号量调集上的操作数组。
int semop(int semid, struct sembuf semoparray[], size_t nops);
semoparray是一个指针,它指向一个信号量操作数组。nops规则该数组中操作的数量。
下面,咱们看一个详细的比如,它创立一个特定的IPC结构的关键字和一个信号量,树立此信号量的索引,修正索引指向的信号量的值,最终咱们铲除信号量。
5.套接口
套接口(socket)编程是完成Linux体系和其他大多数操作体系中进程间通讯的首要方法之一。咱们熟知的WWW服务、FTP服务、 TELNET服务等都是根据套接口编程来完成的。除了在异地的核算机进程间以外,套接口相同适用于本地同一台核算机内部的进程间通讯。