网站首页 > 技术教程 正文
我会用几篇博客总结一下在Linux中进程之间通信的几种方法,我会把这个开头的摘要部分在这个系列的每篇博客中都打出来
进程之间通信的方式
- 管道
- 消息队列
- 信号
- 信号量
- 共享存储区
- 套接字(socket)
在以一切皆文件为原则的Linux系统中,管道也是一种文件(特殊文件),可以使用mkfifo命令创建一个管道文件
在管道文件的前面有一个p来标识管道文件
这次主要说的是通过管道完成进程之间的通信,通过管道通信有两种方式。
一种是匿名管道,一种是命名管道
先来看一段代码
1 #define MAXLINE 80
2 int main
3 {
4 int n;
5 int fd[2];
6 pid_t pid;
7 char line[MAXLINE];
8 if (pipe(fd) < 0)
9 perror("pipe");
10 if ((pid = fork) < 0)
11 perror("fork");
12 if (pid > 0)
13 {
14 //father
15 close(fd[0]);
16 } 17 else 18 { 19close(fd[1]);
20 n = read(fd[0], line, MAXLINE); 21 write(stdout, line, n);//写到标准输出上看一下效果 22 } 23 return 0; 24 25 }这个程序就是一个简单的父子进程之间通过管道进行通信的一个例子,具体的工作过程我用画图的方式展现出来
注意这一个步骤是十分重要的,如果不关闭相应的端口,就无法正确操作管道。
匿名管道主要利用了,创建子进程的时候会把父进程的文件描述符表拷贝一份这个特征,通过这个特征,父子进程就看到了一个公共的资源—管道,并同时拥有对该管道腹泻的权利,那么一方读,一方写,就可以完成进程之间的通信了。
所谓的匿名管道就是说,没有名字。。。你根本不知道这个管道文件存放在哪,也不知道这个管道文件的文件名,唯一跟这个跟管道文件有联系的只有父子进程中的文件描述符。那么根据匿名管道的实现机制,很容易就能看出他的优缺点。
- 管道的n个特征
- 管道是依赖于文件系统的,创建好管道之后,一定要关闭不使用的读写端
- 只有父子进程才可以使用管道通信,也就是所谓的有血缘关系的进程进行进程间通信。(匿名管道独有)
- 管道是基于数据流的,面向字节流!(后面会提到消息队列是面向数据块的,对比来看会好懂一些)
- 管道只能称之为单向数据通信,连半双工都算不上
- 同步与互斥问题不需要考虑了,管道已经考虑了
- 当父子进程退出的时候,管道的生命周期就结束了,也就是说管道的生命周期就是进程
上述就是匿名管道的使用和实现机制,可以看出必须有“亲缘关系”的进程之间才可以使用匿名管道来完成进程间通信。父子进程当然可以,“孙子”进程也是可以的~
那么为了解决只有有亲缘关系的进程才能使用这种方式进行通信的弊端,就有了命名管道的通信方式
简单的来说,我们刚才使用的匿名管道是因为不知道文件名和存放路径,所以只能通过继承文件描述符表来获得跟匿名管道建立联系的方式,如果我们知道路径和管道文件名呢?那不就可以完成非亲缘关系的进程间通信了么
- 函数原型 int mkfifo(const char *pathname,mode_t mode)
- 其中第一个参数pathname就是路径了,mode 就是创建的管道的访问权限umask
- 头文件:#include <sys.stat.h> #include <sys/types.h>
- 返回值,成功返回0,失败返回-1
下面贴上代码
这个是server的
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #define _PATH_NAME_ "./pp"
10
11 int main
12 {
>> 13 char *str="hello world";
14 int fd;
15 if(mkfifo(_PATH_NAME_,0644)<0)·
16 {
17 printf("hahaha\n");
18 printf("mkfifo error %d:%s\n",errno,strerror(errno));
19 }
20 fd=open(_PATH_NAME_,O_WRONLY);
21 write(fd,str,strlen(str));
22 return 0;
23 } 这个是client的
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <fcntl.h>
10
11 #define _PATH_NAME_ "./pp"
12
13
14 int main
15 {
16 int fd;
17 fd=open(_PATH_NAME_,O_RDONLY);
18 char buf[1024]={'\0'};
19 read(fd,buf,1024);
20 printf("%s\n",buf);
21 return 0;
22 } 可以通过open函数来打开分别使用read和write函数来读写管道,当然也可以close掉标准输入输出,做成重定向的那样也是可以的
那么管道有多大呢,我们可以往里面扔多少数据呢?
既然管道也是一个文件,那么肯定有大小上限,这也是其一个缺点,大小有限的,那么我们究竟可以写多少数据放进管道呢,使用man 7 pipe命令打开pipe的说明文档,可以看见这么一段
Pipe capacity
A pipe has a limited capacity. If the pipe is full, then a write(2)
will block or fail, depending on whether the O_NONBLOCK flag is set
(see below). Different implementations have different limits for the
pipe capacity. Applications should not rely on a particular capacity:
an application should be designed so that a reading process consumes
data as soon as it is available, so that a writing process does not
remain blocked.
In Linux versions before 2.6.11, the capacity of a pipe was the same as
the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11,
the pipe capacity is 65536 bytes.
看,我现在的版本是2.6.11之后了,所以是65536字节,之间的版本就是4096字节
最后的最后,来一个管道最大的缺点,管道是基于文件系统的!所以不管是读还是写,都要求访问磁盘进行I/O操作,I/O的速度你懂得,特别慢,所以不适合做多个client的结构,不然会很慢
- 上一篇: Linux 命令行小技巧 –!叹号的用处
- 下一篇: Linux man命令用法
猜你喜欢
- 2025-05-28 通过代码执行或命令执行写Shell
- 2025-05-28 安卓系统再曝ROM级木马“万蓝” 360手机卫士首家查杀
- 2025-05-28 常用液压元件符号
- 2025-05-28 Linux 的这几种搜索方式,你都会了吗?
- 2025-05-28 R语言——带有误差线和显著性标记的柱状图如何做?
- 2025-05-28 管道图纸上常用符号知多少?管网图常用符号大全!值得收藏备用!
- 2025-05-28 收藏 | 记住这些符号,你也能看懂消防工程图!
- 2025-05-28 「干货」Linux 中的零拷贝技术你居然还不知道?
- 2025-05-28 IT运维与网络工程师必会的30个网络抓包/调试工具
- 2025-05-28 linux 系统中正则表达式的使用
欢迎 你 发表评论:
- 10-23Excel计算工龄和年份之差_excel算工龄的公式year
- 10-23Excel YEARFRAC函数:时间的"年份比例尺"详解
- 10-23最常用的10个Excel函数,中文解读,动图演示,易学易用
- 10-23EXCEL中如何计算截止到今日(两个时间中)的时间
- 10-2390%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 10-23计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- 10-23Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 10-23怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- 最近发表
-
- Excel计算工龄和年份之差_excel算工龄的公式year
- Excel YEARFRAC函数:时间的"年份比例尺"详解
- 最常用的10个Excel函数,中文解读,动图演示,易学易用
- EXCEL中如何计算截止到今日(两个时间中)的时间
- 90%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- Excel日期函数之DATEDIF函数_excel函数datedif在哪里
- Excel函数-DATEDIF求司龄_exceldatedif函数计算年龄
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)

本文暂时没有评论,来添加一个吧(●'◡'●)