dedecms 5.7 通用企业网站模板/企业seo案例
管道包括无名管道和有名管道两种,前者用于父进程和子进程间的通信后者用于运行于同一台机,器上的任意两个进程间的通信。
管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等
无名管道
1、 数据自己读不能自己写。
2、 数据一旦被读走,便不在管道中存在,不可反复读取。
3、 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
4、只能在有公共祖先的进程间使用管道。
5、管道不是普通的文件,不属于某个文件系统,其只存在于内存中。
6、从管道读数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便写更多的数据。
7、默认的情况下,从管道中读写数据,最主要的特点就是阻塞问题(这一特点应该记住),当管道里没有数据,另一个进程默认用 read() 函数从管道中读数据是阻塞的。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>#define INPUT 0
#define OUTPUT 1int main()
{int fd[2];pid_t pid; char buf[256];int ret_cnt;// 创建无名管道// 返回两个文件描述符,fd[0]用于读,fd[1]用于写pipe(fd); if((pid = fork()) < 0){printf("Error in fork\n");exit(1);}if(pid > 0) // 父进程{wait(0); printf("parent\n");ret_cnt = read(fd[INPUT], buf, sizeof(buf));printf("%d bytes of data recevied from child\n", ret_cnt);exit(0);}else // 子进程{printf("child\n");write(fd[OUTPUT], "test data", strlen("test data"));}return 0;
}
有名管道
有名管道(named pipe或FIFO)不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
写端
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>#define BUF_SIZE PIPE_BUFint main()
{char buf[BUF_SIZE+1] = "Hello word!";if(access("/tmp/fifo.txt", F_OK) == -1) // 如果不存在{// 创建 有名管道// int mkfifo( const char *pathname, mode_t mode);// pathname: 普通的路径名,也就是创建后 FIFO 的名字// mode: 文件的权限,与打开普通文件的 open() 函数中的 mode 参数相同// 返回值:成功:0; 失败:如果文件已经存在,则会出错且返回 -1int rt = mkfifo("/tmp/fifo.txt", 0777); if(rt != 0){fprintf(stderr, "Could not create fifo %s\n", "/tmp/fifo.txt");exit(EXIT_FAILURE);}}printf("Process %d opening FIFO O_WRONLY\n", getpid());int fd = open("/tmp/fifo.txt", O_WRONLY); // 打开int bytes = 0;if(fd != -1){bytes = write(fd, buf, strlen(buf)); // 写入if(bytes == -1){fprintf(stderr, "Write error on pipe\n");exit(EXIT_FAILURE);}close(fd); // 关闭}else{printf("Open failure\n");exit(EXIT_FAILURE);}printf("Process %d finish, %d bytes had been wroten\n", getpid(), bytes);return 0;
}
读端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>#define BUF_SIZE PIPE_BUFint main()
{char buf[BUF_SIZE+1];memset(buf, '\0', sizeof(buf));printf("Precess %d opening FIFO O_RDONLY\n", getpid());int fd = open("/tmp/fifo.txt", O_RDONLY); // 打开int bytes = 0;if(fd != -1){int cnt = 0;do{cnt = read(fd, buf, BUF_SIZE); // 读取bytes += cnt;}while(cnt > 0);close(fd); // 关闭}else{exit(EXIT_FAILURE);}printf("Process %d finished, %d bytes read\n", getpid(), bytes);return 0;
}
运行写端,运行了读端后,写端才会结束。
运行读端,运行了写端后,读端才会结束。
参考
https://blog.csdn.net/eroswang/article/details/1772350
https://blog.csdn.net/oguro/article/details/53841949
https://blog.csdn.net/tennysonsky/article/details/46315517
https://blog.csdn.net/firefoxbug/article/details/8137762
https://blog.csdn.net/tennysonsky/article/details/46326957