APUE学习笔记7——进程间通信
1 管道
管道一般是一种半双工的进程间通信方式,只能够在具有公共祖先的进程之间使用,比如一个管道由一个进程创建,然后该进程调用fork,之后父、子进程就可以使用该管道。
管道是调用pipe函数创建的。
#include <unistd.h> int pipe(int filedes[]);
/*返回值:成功返回0,出错则返回-1*/
/*经由参数filedes返回两个文件描述符,filedes[0]为读方式打开,filedes[1]则为写方式打开*/
/*进程数据从filedes[1]输出到管道,再从filedes[0]输入到进程*/
调用fork之后做什么取决于想要数据流的方向。对于从父进程到子进程的管道,父进程关闭fd[0],子进程关闭fd[1]。相反的,对于从子进程到父进程的管道,父进程关闭fd[1],子进程关闭fd[0]。

当管道的一端被关闭后,下列两条规则起作用:
- 当读一个写端已经被关闭的管道时,在所有数据被读取之后,read返回0,以指示达到了文件结束处。
- 当写一个读端已经被关闭的管道时,则产生信号SIGPIPE。如果忽略该信号或者捕捉该信号并从其处理函数返回,则write返回-1,errno被置为EPIPE。
常量PIPE_BUF规定了内核中管道缓冲区的大小。
一个简单的进程通讯程序:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX 16
int main(void){ int fd[];
pid_t pid;
char line[MAX]; if(pipe(fd) < ){ //初始化管道
printf("pipe error");
exit();
} if(pid = fork() < ){
printf("fork error");
exit();
}else if(pid != ) { //父进程
close(fd[]);
write(fd[], "hello!", );
}else{ //子进程
close(fd[]);
read(fd[], line, MAX);
printf(line);
} exit();
}
2 popen和pclose函数
标准I/O库提供了两个管道函数popen和pclose。这两个函数实现的操作是:创建一个管道,调用fork产生一个子进程,关闭管道的不使用端,exec执行一个shell以运行命令,然后等待命令终止。
#inlcude <stdio.h> FILE *popen(const char *cmdstring, const char *type);
/*返回值:成功返回文件指针,出错返回NULL*/ int pclose(FILE *fp);
/*返回值:cmdstring执行后的终止状态,出错返回-1*/
如果type是“r”,则popen返回的文件指针指向cmdstring的标准输出。如果type是“w”,则popen返回的文件指针指向cmdstring的标准输入。
cmdstring由系统shell按下列方式执行:
#sh -c cmdstring
3 FIFO
FIFO有时被称为命名管道。普通管道只能由相关进程使用,这些相关进程的共同祖先进程创建了这个管道。但是通过FIFO,不相关的进程也能交换数据。
创建FIFO类似于创建文件,实际上FIFO的路径名存在文件系统中。
#include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
/*返回值:成功返回0,出错返回-1*/
mkfifo函数中mode参数与open函数中的mode参数相同。创建了FIFO之后就可以用open函数打开它。一般的文件I/O函数(如close、read、write、unlink等)都可以用于FIFO。
打开FIFO时,非阻塞标志(O_NONBLOCK)产生下列影响:
- 默认情况(不指定O_NONBLOCK),一个进程以读的方式open FIFO会阻塞,一直到另一个进程以写的方式open该FIFO。类似的,一个进程以写的方式open FIFO会阻塞,一直到另一个进程以读的方式open该FIFO。
- 如果指定了O_NONBLOCK,则一个进程以读的方式open FIFO会立即返回。但是,如果没有其他进程以读的方式open FIFO,则一个进程以写的方式open FIFO将出错返回-1,并将errno置为ENXIO。
FIFO有下面两种用途:
- FIFO由shell命令使用以便将数据从一个管道线传送到另一条管道线,无需创建中间临时文件。
- FIFO用于客户进程-服务器进程之间传输数据。
4 消息队列、信号量和共享存储器
消息队列、信号量和共享存储器统称为XSI IPC。每个内核之中的IPC结构都用一个非负整数的标识符加以应用。与文件描述符不同,IPC标识符不是一个小的整数。当一个IPC结构被创建,以后又被删除时,与这种结构相关的标识符加1,直至到达最大值然后归零。
(未完待续)
APUE学习笔记7——进程间通信的更多相关文章
- APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause
转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...
- APUE学习笔记3_文件IO
APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...
- apue学习笔记(第十七章 高级进程间通信)
本章介绍一种高级IPC---UNIX域套接字机制,并说明它的应用方法 UNIX域套接字 UNIX域套接字用于在同一台计算机上运行的进程(无关进程)之间的(全双工)通信.相比于因特网套接字,UNIX域套 ...
- apue学习笔记(第十五章 进程间通信)
本章将说明进程之间相互通信的其它技术----进程间通信(IPC) 管道 管道只能在具有公共祖先的两个进程之间只用.通常,一个管道由一个进程创建,在进程调用fork后,这个管道就能在父进程和子进程之间使 ...
- apue学习笔记(第一章UNIX基础知识)
总所周知,UNIX环境高级编程是一本很经典的书,之前我粗略的看了一遍,感觉理解得不够深入. 听说写博客可以提高自己的水平,因此趁着这个机会我想把它重新看一遍,并把每一章的笔记写在博客里面. 我学习的时 ...
- APUE学习笔记-一些准备
从开始看APUE已经有快一个星期了,由于正好赶上这几天清明节放假,难得有了三天空闲假期可以不受打扰的学习APUE,现在已经看完前六章了,里面的大部分例程也都亲自编写,调试过了.但总觉得这样学过就忘,因 ...
- APUE学习笔记(2):lseek()练习与文件洞
对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...
- APUE学习笔记(1):APUE运行环境
APUE全称<Advanced Programming in the UNIX Environment>(UNIX环境高级编程) 书中例子大都使用作者自己写的头文件,所以需要解决一下,还好 ...
- apue学习笔记(第十六章 网络IPC:套接字)
本章将考察不同计算机(通过网络连接)上的进程相互通信的机制:网络进程间通信. 套接字描述符 正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字. 许多处理文件描述符函数(如read和writ ...
随机推荐
- Swift - 反射(Reflection)的介绍与使用样例(附KVC介绍)
1,反射(Reflection) 对于C#.Java开发人员来说,肯定都对反射这个概念相当熟悉.所谓反射就是可以动态获取类型.成员信息,同时在运行时(而非编译时)可以动态调用任意方法.属性等行为的特性 ...
- 分层、链式分析、url、联系的长度
分层.链式分析.url.联系的长度. 分层结构符合软件处理的工具链性和步骤性: 分层的每一次都是一个节点或步骤: 链式结构普遍存在于自然界,比如食物链: 联系是普遍存在的,不只是两个事物间的联系,而且 ...
- Selenium3+python自动化008-常用操作
一.元素常用操作 1. clear() 清除文本 2. send_keys() 模拟输入 3. click() 单击元素 4.get_attr ...
- -webkit-appearance: none; 去除浏览器默认样式
-webkit-appearance: none; 去除浏览器默认样式
- Javase 简单代码练习
public class Test10 { public static void main(String[] args) { System.out.println("------------ ...
- springboot版本控制
HandlerMapping通过继承InitializingBean接口在完成实例后,扫描所有的Controller和标识RequestMapping的方法,缓存这个映射对应关系.然后在应用运行的时候 ...
- keyup.enter.native&click.native.prevent
vue 监听键盘回车事件 @keyup.enter || @keyup.enter.native vue运行为v-on在监听键盘事件时,添加了特殊的键盘修饰符: <input v-on:keyu ...
- js进度条插件pace.js
主要用到themes文件夹和pace.js文件
- Nginx全局变量
一.全局变量 $args #请求中的参数值 $query_string #同 $args $arg_NAME #GET请求中NAME的值 $is_args #如果请求中有参数,值为"?&qu ...
- JS中增加日期格式化原型函数之prototype
/** * javascript Date format(js日期格式化) * 对Date的扩展,将 Date 转化为指定格式的String 月(M).日(d).小时(h).分(m).秒(s).季度( ...