Linux下进程间通信方式

1.普通管道,是一种半双工,数据只能从一个方向流向另一个方向,只能用在亲缘进程之间,发送进程将数据送入管道,接受进程从管道中读取数据。使用int pipe(int filedis[2]);函数创建一个普通管道,当一个管道被创建的时候,也创建了两个文件描述符,fieldis[0]是读管道 ,fieldis[1]是写管道。通常是先创建一个管道,然后通过fork函数创建子进程。必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符。否则,会创建两个管道,因为父子进程共享同一段代码段,都会各自调用pipe(),即建立两个管道,出现异常错误。

int pipe_fd[2];

pipe(pipe_fd);  创建一个管道

write(pipe_fd[1],"Hello",5) 向写管道中写入数据。

read(pipe_fd[0],buf_r,100) 从读管道中读出数据。

关闭管道,只需要关闭这两个文件描述符就可以了。close(pipe_fd[0]);  close(pipe_fd[1]);

 

2.命名管道,和普通管道一样也是一种半双工,数据只能从一个方向流向另一个方向,只不过命令管道不仅仅可以使用在亲缘进程之间,不相关的进程也可以使用命名管道进行通信。

命名管道创建mkfifo("zieckey_fifo",0777);

写管道打开 fd=open("zieckey_fifo",O_WRONLY); //阻塞写,open阻塞,除非遇到读

往管道中写入数据 write(fd,s,sizeof(s));

读管道打开fd=open("zieckey_fifo",O_RDONLY); //阻塞读 open阻塞,除非遇到写

从管道中读取数据read(fd,buf,sizeof(buf));

从命名管道的创建和打开,我们可以看出命名管道好像就是一个文件,其实,命名管道就是一种特殊类型的文件,在

文件系统中以文件名的形式存在。

打开方式最常见的是阻塞读+阻塞写 非阻塞读+阻塞写

3.消息队列,消息队列提供了从一个进程向另一个进程发送数据块的方法,消息队列和命名管道很相似。

消息队列是一个进程向消息队列中发送消息,使用msgsnd函数,另一个进程使用msgrcv函数从消息队列中接受消息。

消息队列的优势在于,消息队列独立于进程存在,避免了同步命名管道的打开和关闭带来的困难。

同时消息队列可以避免同步和阻塞问题,不需要进程来提供同步方法。

另外接受进程可以通过消息类型有选择的接受消息,不像命名管道那样只能默认接受。

4.共享内存 共享内存就是允许两个不相关的进程访问同一逻辑内存,共享内存是一种在两个正在运行的进程间

共享和传递数据的一种非常有效的方式。两个不同的进程可以将同一段共享内存连接到各自的字节地址空间,就像是

这段共享内存是分配给他们的一样,一个进程修改共享内存中的数据,其他进程立刻就会收到影响。

特别注意一点,共享内存没有任何阻塞同步机制,也就是一个进程正在修改一个数据,并不会阻塞其他进程读取这个

数据,所以共享内存需要另外提供阻塞同步机制,例如信号量。

5.信号量 信号量是一个特殊的变量,我们通常通过信号来解决多个进程对同一资源的访问竞争的问题,使在任一时刻只能有一个执行线程访问代码的临界区域,也可以说它是协调进程间的对同一资源的访问权,也就是用于同步进程的。

例如两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

6.套接字更为一般的进程间通信机制,可用于不同机器之间的进程间通信


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaozonglu/article/details/49927431
文章标签: 进程间通信
个人分类: 计算机基础
上一篇InnoDB知识点整理
下一篇InnoDB深入理解
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭