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]。

当管道的一端被关闭后,下列两条规则起作用:

  1. 当读一个写端已经被关闭的管道时,在所有数据被读取之后,read返回0,以指示达到了文件结束处。
  2. 当写一个读端已经被关闭的管道时,则产生信号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有下面两种用途:

  1. FIFO由shell命令使用以便将数据从一个管道线传送到另一条管道线,无需创建中间临时文件。
  2. FIFO用于客户进程-服务器进程之间传输数据。

4 消息队列、信号量和共享存储器

消息队列、信号量和共享存储器统称为XSI IPC。每个内核之中的IPC结构都用一个非负整数的标识符加以应用。与文件描述符不同,IPC标识符不是一个小的整数。当一个IPC结构被创建,以后又被删除时,与这种结构相关的标识符加1,直至到达最大值然后归零。

(未完待续)

APUE学习笔记7——进程间通信的更多相关文章

  1. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  2. APUE学习笔记3_文件IO

    APUE学习笔记3_文件IO Unix中的文件IO函数主要包括以下几个:open().read().write().lseek().close()等.这类I/O函数也被称为不带缓冲的I/O,标准I/O ...

  3. apue学习笔记(第十七章 高级进程间通信)

    本章介绍一种高级IPC---UNIX域套接字机制,并说明它的应用方法 UNIX域套接字 UNIX域套接字用于在同一台计算机上运行的进程(无关进程)之间的(全双工)通信.相比于因特网套接字,UNIX域套 ...

  4. apue学习笔记(第十五章 进程间通信)

    本章将说明进程之间相互通信的其它技术----进程间通信(IPC) 管道 管道只能在具有公共祖先的两个进程之间只用.通常,一个管道由一个进程创建,在进程调用fork后,这个管道就能在父进程和子进程之间使 ...

  5. apue学习笔记(第一章UNIX基础知识)

    总所周知,UNIX环境高级编程是一本很经典的书,之前我粗略的看了一遍,感觉理解得不够深入. 听说写博客可以提高自己的水平,因此趁着这个机会我想把它重新看一遍,并把每一章的笔记写在博客里面. 我学习的时 ...

  6. APUE学习笔记-一些准备

    从开始看APUE已经有快一个星期了,由于正好赶上这几天清明节放假,难得有了三天空闲假期可以不受打扰的学习APUE,现在已经看完前六章了,里面的大部分例程也都亲自编写,调试过了.但总觉得这样学过就忘,因 ...

  7. APUE学习笔记(2):lseek()练习与文件洞

    对于lseek函数早在大一的C语言课上就有接触,但是几乎没有使用过,只记得是和文件偏移操作相关的 看了APUE上的示例,又使用od工具查看了内容,果然很神奇,很新鲜 figure3.2.c [c] # ...

  8. APUE学习笔记(1):APUE运行环境

    APUE全称<Advanced Programming in the UNIX Environment>(UNIX环境高级编程) 书中例子大都使用作者自己写的头文件,所以需要解决一下,还好 ...

  9. apue学习笔记(第十六章 网络IPC:套接字)

    本章将考察不同计算机(通过网络连接)上的进程相互通信的机制:网络进程间通信. 套接字描述符 正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字. 许多处理文件描述符函数(如read和writ ...

随机推荐

  1. RxSwift學習教程之基礎篇

    前言 我們在 iOS 開發過程中,幾乎無時無刻都要面對異步事件的處理.例如,按鍵點擊.數據保存..音頻後臺播放.交互動畫展示.這些事件並不具備特定時序性,甚至它們可能同時發生. 雖然 Apple 提供 ...

  2. 优动漫PAINT动画创作功能介绍

    优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,它是一款功能强大的漫画.插画绘制软件,它搭载了绘制漫画和插画所需的所有功能,包括丰富的笔工具.超强的笔压感应和手 ...

  3. Co-prime HDU - 4135_容斥计数

    Code: #include<cstdio> #include<cstring> #include<cmath> #include<iostream> ...

  4. 洛谷P1540 机器翻译 水题 模拟

    注意一下细节,尤其是更新minv时不要更新错. Code: #include<vector> #include<iostream> #include<cstdio> ...

  5. 关闭浏览器 清除session

    捕获关闭浏览器的事件 关于关闭IE清空session的总结 Session过期会清楚session 还可以手动清除session实现关闭浏览器时清除session的方法

  6. python面向对象的三大特性之一多态

    多态 多态的特性是调用不同的子类将会产生不同的行为,而无需明确知道这个子类实际上是什么 说白了就是,不同的对象调用相同的方法,产生不同的行为 例如:s1是字符串类型,w1是列表,两个完全不同的对象,他 ...

  7. vue 动态添加路由 require.context()

    之前的写法 'use strict' import Vue from 'vue' import MessageBroadcast from 'page/MessageBroadcast' import ...

  8. 训练1-W

    有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值.编程输出该平均值序列. Input 输 ...

  9. nyoj254-编号统计

    编号统计 时间限制:2000 ms  |  内存限制:65535 KB 难度:2 描述 zyc最近比较无聊,于是他想去做一次无聊的统计一下.他把全校同学的地址都统计了一下(zyc都将地址转化成了编码) ...

  10. CentOS 7下搭建高可用集群

    一 .安装集群软件 必须软件pcs,pacemaker,corosync,fence-agents-all,如果需要配置相关服务,也要安装对应的软件. 二.配置防火墙1.禁止防火墙和selinux# ...