linux系统中的进程通信(管道和有名管道)
来源:互联网 发布:java版本 编辑:程序博客网 时间:2024/05/21 22:38
进程通信:多个进程需要协调工作,需要进行数据的交换。
管道:是unix中进程通信的一种方式,管道的一端连接着输入另一段连接这数据的输出。
管道(无名管道):用于父子进程之间的通信。
有名管道:由于不同进程之间的通信。
匿名管道:
#include <unistd.h>int pipe(int fdes[2]) /*创建匿名管道*/fdes:管道的输入、输出端的描述字。
成功时返回 0,失败时返回 -1
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>const int BUFFMAX = 100; int main(){pid_t pid;int n,mypipe[2];char buffer[BUFFMAX + 1],*some = "hello world!";if(pipe(mypipe)) /*创建管道*/{fprintf(stderr,"faile!\n");exit(1);}if((pid = fork()) < 0) /*创建子进程*/{fprintf(stderr,"faile!\n");exit(1);}if(pid == 0) /*如果是子进程*/{close(mypipe[1]); /*关闭子进程管道的输出端*/n = read(mypipe[0],buffer,BUFFMAX); /*从管道中读取数据*/fprintf(stdout,"Pid %d Read %d %s\n",getpid(),n,buffer);}else{close(mypipe[0]); /*关闭父进程管道的输入端*/n = write(mypipe[1],some,strlen(some)); /*向管道写入数据*/ fprintf(stdout,"Pid %d Write %d %s\n",getpid(),n,some);}exit(0);}
一般通过fork创建子进程是为了调用exec( )系列函数运行新的程序,如果调用exec( )则子进程从父进程继承的文件描述已经被新的程序代替,在调用exec( )函数之前可以先把管道的输入端重定向到标准输入端,从而是新的程序能过通过管道和父进程通信。重定向一般使用dup2( old,new)函数实现,如果描述字new打开则先关闭,再用new代替old,这个函数的操作是原子。
#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>const int Max = 100;int main(){int fd[2];pid_t pid;char buffer[Max];if(pipe(fd)) /*创建管道*/{fprintf(stderr,"make falie!\n");exit(1);}if((pid = fork()) < 0) /*创建子进程*/{fprintf(stderr,"pid faile!\n");exit(1);}if(pid == 0) /*如果是子进程*/{close(fd[1]); /*关闭子进程管道的输出端*/dup2(fd[0],0); /*把子进程的输入端重定向到标准输入端*/close(fd[0]); /*关闭不需要的描述字*/if(execl("/bin/cat","cat",NULL) < 0) /*调用execl()创建新的程序*/{fprintf(stderr,"make falie!\n");exit(1);}}else /*如果是子进程*/{close(fd[0]); /*关闭父进程管道的标准输入*/fprintf(stdout,"Plase input line date!\n");dup2(fd[1],1); /*为了使用pets函数,把父进程管道出重定向到标准输出*/close(fd[1]); /*关闭不用的描述字*/while(gets(buffer) != NULL) puts(buffer);}exit(0);}
有名管道(FIFO)
#include <sys/types.h>
#include <sys/stat.h>int mkfifo (const char *path,mode_t mode); /*创建有名管道*/path:有名管道的路径级名字。
mode:有名管道的文件权限。
失败返回0
创建管道,并读取内容,如果还没有向管道写入内容,将阻塞等待。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define FIFO_FILE "fifo_file" /*有名管道的名称*/#define Max 5int main(){int fifo,fd;int n; char buff[Max]; if(access(FIFO_FILE,F_OK) < 0) /*测试文件是否存在*/{if(mkfifo(FIFO_FILE,0666) < 0) /*创建管道*/{ fprintf(stderr,"mkdir falie!\n"); exit(1);}}if((fd = open(FIFO_FILE,O_RDONLY)) < 0) /*打开文件*/{fprintf(stderr,"Open falie!\n");exit(1);}printf("%d Open %s\n",getpid(),FIFO_FILE);while((n = read(fd,buff,Max)) > 0) /*读取管道内容*/{fprintf(stdout,"%d read %s\n",getpid(),buff);}close(fd); /*关闭文件*/fprintf(stdout,"%d over\n",getpid());exit(0);}
打开文件向管道写入数据,当管道内容还没有读取时将阻塞,等待读取完毕在写入。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#define FIFO_FILE "fifo_file"#define Max 100int main(){int fifo,fd;int n; char buff[Max + 1] = "hello fifo"; if((fd = open(FIFO_FILE,O_WRONLY)) < 0) /*打开文件*/{fprintf(stderr,"fifo1 Open falie!\n");exit(1);}printf("%d Open %s\n",getpid(),FIFO_FILE);n = write(fd,buff,strlen(buff)); /*向管道内写入文件*/fprintf(stdout,"%d write %d\n",getpid(),n);close(fd); /*关闭文件*/fprintf(stdout,"%d over\n",getpid());exit(0);}
0 0
- linux系统中的进程通信(管道和有名管道)
- 进程间通信-管道(有名管道和无名管道)
- linux中的进程通信-信号量和有名管道
- linux 进程间通信之管道和有名管道
- linux进程通信-有名管道
- linux进程通信--有名管道
- Linux系统管道和有名管道的通信机制
- Linux--进程间通信(管道及有名管道FIFO)
- Linux--进程间通信(管道及有名管道FIFO)
- Linux--进程间通信(管道及有名管道FIFO)
- Linux中的通信机制(1) 管道和有名管道
- Linux进程间通信(一)之无名管道(PIPE)和有名管道(FIFO)
- Linux环境进程间通信(一)管道和有名管道
- linux系统中的有名管道(FIFO)
- linux系统中的有名管道
- 进程通信--有名管道
- 【Linux系统编程】进程间通信--有名管道
- linux进程通信----FIFO(有名管道)
- XCode 添加复制/删除行快捷键
- ASP.NET笔记
- setImageResource和setImageDrawable和setImageBitMap区别
- Logstash and Log4j
- curl、wget命令总结
- linux系统中的进程通信(管道和有名管道)
- 程序员常去网站
- TCP三次握手和四次挥手以及缺陷(详细)
- Cocos2d-x-3.10 addImageAsync异步加载图片
- viewDidLoad 和 loadView 的区别,并且viewDidLoad可能被调用两次(或者多次)
- 或计算机体系结构
- 2. Add Two Numbers
- iOS开发中用户密码应该保存在哪里
- nginx学习(三)——基础概念之connection