IPC之管道编程(1)
来源:互联网 发布:php 积分商城 开源 编辑:程序博客网 时间:2024/06/16 17:59
1、IPC
IPC:是指进程间通信(Inter Process Cnmunication)。进程间相互通信的方式主要有以下6种:
(1)管道(pipe)和有名管道(FIFO)。
(2)信号(signal)
(3)消息队列
(4)共享内存
(5)信号量
(6)套接字(socket)
2、进行进程间通信的目的
(1)数据传输:一个进程需要将它的数据发送给另一个进程。
(2)资源共享:多个进程之间共享同样的资源。
(3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件。
(4)进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。
3、管道通信
管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。
4、管道创建
管道包括无名管道和有名管道两种,前者用于父进程和子进程之间的通信;后者用于统一系统的任意两个进程间的通信。
(1) 无名管道由pipe()函数创建:
#include <unistd.h>int pipe(int fd[2]);
当一个管道建立时,它会创建两个文件描述符:
fd[0]用于读管道,fd[1]用于写管道。
(2)命名管道由mkfifo()函数创建:
#include <sys/stat.h>int mkfifo(const char *path, mode_t mode);int mkfifoat(int fd, const char *path, mode_t mode);
mkfifo() 中 path 需要指定为文件的绝对路径。
nkfifoat() 当 fd 为 AT_FDCWD时,则路径名以当前目录开始。
mode 创建一个命名管道时的属性。
一旦创建了FIFO,就可以用 open 打开它,一般的文件访问函数(read、write、close等)都可用于FIFO。
当 open 一个FIFO时,非阻塞标志(O_NONBLOCK)会产生以下影响。
1、没有使用O_NONBLOCK:访问要求无法满足要求时进程将阻塞,如试图读取空FIFO时,将导致进程阻塞。
2、使用O_NONBLOCK:访问要求无法满足时不阻塞,立刻出错返回,errno 是 ENXIO
5、管道关闭
关闭管道只需要将文件描述符关闭即可,可以使用普通的close()函数逐个关闭。
6、管道通信demo
(1)无名管道
demo:
#include <apue.h>int main(int argc, const char *argv[]){ int fd[2]; pid_t pid; int n; char line[MAXLINE]; /* 创建管道 */ if (pipe(fd) < 0) err_sys("pipe error"); /* 创建子进程 */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid > 0){ //父进程 close(fd[0]); write(fd[1], "Hello World\n", 12); close(fd[1]); waitpid(pid, NULL, 0); //等待子进程退出 exit(0); } else{ //子进程 close(fd[1]); sleep(1); //先让父进程有时间写数据 n = read(fd[0], line, MAXLINE); write(STDOUT_FILENO, line, n); close(fd[0]); exit(0); } return 0;}
注意:系统必须先调用pipe()再调用fork(),不然会产生两个进程,子进程也不会继承文件描述符!
(2)命名管道通信demo
创建两个进程,一个为写进程,另一个为读进程。
/**************//* 读进程 *//*************/#include <apue.h>#include <fcntl.h>#define FIFO "/tmp/myfifo"int main(int argc, char *argv[]){ char buf_rd[100]; int fd; int bytes_rd; /* 创建管道 */ if ((mkfifo(FIFO, O_CREAT | O_EXCL) < 0) && (errno != EEXIST)) printf("Can't create fifo\n"); printf("Preparing for reading bytes...\n"); memset(buf_rd, 0, sizeof(buf_rd)); /* 打开管道 */ fd = open(FIFO, O_RDONLY | O_NONBLOCK); if (fd == -1){ perror("Open fifo error"); exit(10); } while(1){ memset(buf_rd, 0, sizeof(buf_rd)); if (bytes_rd = read(fd, buf_rd, 100) == -1) if (errno == EAGAIN) printf("No data yet\n"); printf("Read %s from FIFO\n", buf_rd); sleep(1); }}
/**************//* 写进程 *//*************/#include <apue.h>#include <fcntl.h>#define FIFO_SERVICE "/tmp/myfifo"int main(int argc, char *argv[]){ char buf_wr[100]; int bytes_wr; int fd; int i; if (argc == 1){ printf("Please send something\n"); printf("Usage : ./a.out string ...\n"); exit(1); } for (i = 1; i < argc; i++){ strcat(buf_wr, " "); strcat(buf_wr, argv[i]); } fd = open(FIFO_SERVICE, O_WRONLY | O_NONBLOCK); if (fd == -1){ perror("Open FIFO error"); exit(10); } if ((bytes_wr = write(fd, buf_wr, 100)) == -1){ if (errno == EAGAIN) printf("The FIFO has been read yet, Please try agian\n"); } else printf("Write%s to FIFO\n", buf_wr);}
- IPC之管道编程(1)
- 【Linux编程】IPC之管道
- windows编程 IPC 管道
- 进程间通信(IPC)之管道
- [总结]IPC之管道
- linux IPC之管道
- IPC通信之管道
- IPC通信之管道
- linux IPC 之管道
- Linux-IPC之管道
- IPC通信之-管道
- IPC之管道详解
- IPC之管道详解
- IPC之---管道
- Linux环境编程之IPC进程间通信(二):管道
- linux系统编程学习day5--IPC之管道
- IPC-管道(匿名管道)
- 进程间通信(IPC)1 ------ 管道
- Python 标准库一览(Python进阶学习)
- 排列与组合的JAVA通用算法
- 36. MySQL 命令
- 后来
- Linux系统的文件传输
- IPC之管道编程(1)
- 用KS和pxe自动安装linux系统
- 倒排索引
- POJ 1426 Find The Multiple
- 通过内容提供者获取手机上的音乐资源
- [PAT乙级]1039. 到底买不买(20)
- 7.24 STL专题
- C语言:使用COORD结构体实现光标随方向键移动
- 软件安装和yum库的配置