linux 单向队列,Linux 伍之型 进程间通信(管道、共享内存、消息队列、信号量)...

看进程之间怎么说悄悄话~

因为进程有独立性,有个字

先理解一下,进程通信 : 不同进程之间传播或交换信息

那为什么要进程通信呢? 协同运行(数据传输、数据共享、进程控制),项目模块化(低耦合)。

那为什么进程通信需要os控制呢? 为了保证进程的独立性,让每个进程稳定运行,用户很难控制,难事都交给os做吧~

通信原理 : 给多个进程提供一个都能访问到的缓冲区。

根据使用场景,我们能划分为以下几种通信 :

1.管道(匿名管道、命名管道)

管道是从Unix继承下来的进程通信机制,其思想就是 : 在内核中创建一个缓冲区让通信双方传递信息。"管道"是半双工通信(单向传递信息)。

cd0fdee991f9a0e89b2694b84e07f135.png

匿名管道 :创建的缓冲区没有标识 ,只能用于具有亲缘关系的进程通信。

通信流程及代码:

b599c2c80a4b9500d6a619b99d846656.png

04caf884560f2420fc136d0ee85b21a2.png

/** 匿名管道接口的基本使用*/#include#include#include#include#include

intmain()

{//创建管道 必须在子进程创建之前//int pipe(int pipefd[2]);//pipefd : 用于获取管道中的操作描述符//pipefd[0] : 用于从管道中读取数据//pipefd[1] : 用于向管道中写入数据//返回值 : 成功 0 失败 -1

int pipefd[2];int ret =pipe(pipefd);if(ret < 0)

{

perror("pipe error");return -1;

}int pid =fork();if(pid < 0)

{return -1;

}else if(pid == 0)

{//子进程关闭写端

close(pipefd[1]);//子进程--读取管道中的数据

char buff[1024] = {0};

read(pipefd[0],buff,1023);

printf("buff:[%s]\n",buff);

}else{//父进程关闭读端

close(pipefd[0]);//父进程--向管道中写入数据

char *ptr = "do you like me ?";

write(pipefd[1],buff,strlen(ptr));

}return 0;

}

管道的读写特性 :

如果管道中没有数据,则read会阻塞,直到读取到数据

如果管道中数据满了,则write会阻塞,直到有数据被读取出去

如果管道中所有写端都被关闭,那么读端读完管道中的数据之后,会返回0

如果管道中所有读端都被关闭,那么写端写入数据的时候会触发异常,退出进程

管道特点 :

1.半双工通信,数据只能一个方向流动

2.读写特性

3.内核会对管道进行同步与互斥操作(如果管道读写数据大小<=PIPE_BUF,读写操作将是原子性操作,是不可中断的)

4.提供字节流(不包含边界的连续流)服务(数据的传输比较灵活,但是有可能造成数据粘连(数据没有边界))

5.生命周期随进程退出而退出

下面,用匿名管道实现ls | grep 命令:

//ls|grep的模拟实现

#include#include#include

intmain()

{//创建匿名管道

int pipefd[2];int ret =pipe(pipefd);if(ret<0)

{

perror("pipe error\n");return -1;

}int pid1=fork();if(pid1==0)

{//ls --- 写入到标准输出进行打印//标准输出重定向到管道写端

close(pipefd[0]);

dup2(pipefd[1],1);

execlp("ls","ls",NULL);

exit(0);

}int pid2=fork();if(pid2==0)

{//grep make --- 从标准输入读取数据//标准输入重定向到管道读端

close(pipefd[1]);

dup2(pipefd[0],0);

execlp("grep","grep","make",NULL);

exit(0);

}//wait之前关闭管道,防止影响子进程之间的管道交流

close(pipefd[0]);

close(pipefd[1]);

wait(NULL);

wait(NULL);return 0;

}

命名管道 : 可见于文件系统创建的一个管道文件,所有进程都可以通过打开文件获取内核管道的文件描述符。

特点 :能让同一机器任意进程都可以进行通信。

打开特性 :

管道文件如果被只读/只写方式打开,将阻塞,直到该文件被只写/只读方式打开;

被读写方式打开,不阻塞。

通信流程及代码 :

写端mkfifo创建管道文件->读端打开管道->两端可以进行单向通信了

//命名管道 读端demo

#include#include#include#include#include#include

intmain()

{int fd=open("./test.fifo",O_RDONLY);while(1)

{char buff[1024]={0};int ret=read(fd,buff,1023);if(ret>0)

{

printf("client say:%s\n",buff);

}else if(ret == 0)

{

printf("write close!\n");return -1;

}else{

perror("read error");return -1;

}

}

close(fd);return 0;

}

//命名管道基本使用 写端demo//int mkfifo(cosnt char* pathname,mode_t mode)//mode : 权限 返回值: 成功0 失败-1

#include#include#include#include#include#include

intmain()

{int ret = mkfifo("./test.fifo",0664);if(ret<0)

{

perror("mkfifio error");return -1;

}int fd = open("./test.fifo",O_WRONLY);if(fd<0)

{

perror("open error");return -1;

}

printf("open fifo success!\n");while(1)

{char buff[1024] = {0};

scanf("%s",buff);

write(fd,buff,strlen(buff));

printf("buff:[%s]\n",buff);

}

close(fd);return 0;

}

运行演示 :

b871042ac928d63b3d8722d1f55d06f1.png

89ff46c0fabfa73fab1e05acacb7151a.png

cd5e012b16d01e04796f83c4c4ea2341.gif

原文:https://www.cnblogs.com/Duikerdd/p/11737374.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值