1.标准流管道
管道操作支持文件流模式,用来创建链接还有一个进程的管道,通过函数popen和pclose
popen的详细介绍在本blog:Linux
多进程学习中有具体介绍
2.无名管道(PIPE)
特点:
1)仅仅能在亲缘关系进程间通信(父子或兄弟)
2)半双工(固定的读端和固定的写端)
3)是特殊文件,能够用read,write等,在内存中
管道函数原型:
#include<unistd.h>
int pipe(int fds[2]);
管道在程序中用一对文件描写叙述符表示,一个是可读属性,一个是可写属性:fds[0]读,fds[1]写
两个进程必须有继承关系,才干继承这对打开的文件描写叙述符
int main(){ int fds[2]; if(pipe(fds)==-1){ perror("pipe:"); return 0; } char buf[1024]=""; if(fork()==0){ close(fds[1]); while(memset(buf,0,sizeof(buf))){ if(read(fds[0],buf,1024)==0){//当管道里没有数据的时候就退出 break; } printf("child:read:"); puts(buf); } exit(1); } else{ close(fds[0]); // char p[1024]; // char *p="Hello world!"; while(memset(buf,0,1024),fgets(buf,1024,stdin)!=NULL) write(fds[1],buf,1024); close(fds[1]); printf("parents,finish "); wait(NULL);//wait一定要放在close的后面,由于仅仅有先将父进程的fds[1]关掉,当子进程没有数据读的时候才会退出,否则会导致死锁 } }
3命名管道(FIFO)
无名管道仅仅能在亲缘关系的进程间通信大大限制的管道的使用,有名管道突破了这个限制,通过制定路径名的范式实现不相关的进程通信
3.1创建,删除FIFO文件
创建FIFO文件与创建普通文件非常类似,仅仅是创建之后的文件FIFO
创建FIFO文件的函数原型
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname,mode_t mode);
參数pathname为要创建的FIFO文件的全路径名;
參数mode为文件的訪问权限
创建成功返回0,创建失败为-1
删除FIFO文件的函数原型为
int unlink(const char *pathname);
样例:
#include<iostream> using namespace std; int main(int argc,char *argv[]){ if(mkfifo(argv[1],0666)==-1){ perror("ew"); return 0; } unlink(argv[1]); }
3.2打开,关闭FIFO文件
对于FIFO类型的文件的打开/关闭更普通文件一样,都是用open和close函数。用O_WRONLY打开FIFO的写入端,用O_RDONLY选项,则打开FIFO的读入端,写入读入端都能够被几个进程同一时候打开。
fd_recv=open(argv[1],O_RDONLY);
fd_send=open(argv[2],O_WRONLY);
if(fd_send==-1){
perror("fd_send");
exit(1);
}
3.3读写FIFO
读:
fd_recv=open(argv[1],O_RDONLY);
char buf_recv[1024]="";
if(read(fd_recv,buf_recv,1024)!=0) write(1,buf_recv,strlen(buf_recv));
close (fd_recv)
写:
fd_send=open(argv[2],O_WRONLY);
char buf_send[1024]="";
if(fgets(buf_send,1024,stdin)!=NULL) write(fp_send,buf_send,strlen(buf_send));
close(fd_send);
程序示范:
pork_send.c与pork_recv.c聊天
使用fork开辟留一个进程,两个程序能够进行聊天功能
/************************************************************************* > File Name: pork_send.c > Author: yang > Mail:826123027@qq.com > Created Time: 2014年08月22日 星期五 19:54:08 ************************************************************************/ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<memory.h> int main(int argc,char *argv[]){ if(mkfifo(argv[1],0666)==-1){ perror("mkfifo1"); exit(1); } int fd_send,fd_recv; fd_send=open(argv[1],O_WRONLY); fd_recv=open(argv[2],O_RDONLY); char buf_recv[1024]=""; char buf_send[1024]=""; printf("opening! "); if(fork()==0){//开皮一个进程,用来接受信息 close(fd_send); while(memset(buf_recv,0,sizeof(buf_recv)),read(fd_recv,buf_recv,1024)>0){ write(1,buf_recv,strlen(buf_recv)); } close(fd_recv); exit(1); } close(fd_recv); while(memset(buf_send,0,sizeof(buf_send)),fgets(buf_send,1024,stdin)!=NULL){ write(fd_send,buf_send,strlen(buf_send));//用来发送信息 } close(fd_send); wait(NULL); }
/************************************************************************* > File Name: pork_recv.c > Author: yang > Mail:826123027@qq.com > Created Time: 2014年08月22日 星期五 20:12:32 ************************************************************************/ #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<memory.h> #include<stdio.h> int main(int argc,char *argv[]){ if(mkfifo(argv[2],0666)==-1){ perror("mkfifo2"); exit(1); } int fd_send,fd_recv; fd_recv=open(argv[1],O_RDONLY);//注意这里与上面程序的这个位置有所不一样 fd_send=open(argv[2],O_WRONLY); char buf_recv[1024]=""; char buf_send[1024]=""; printf("opening! "); if(fork()==0){//接受信息 close(fd_send); while(memset(buf_recv,0,sizeof(buf_recv)),read(fd_recv,buf_recv,1024)>0){ write(1,buf_recv,strlen(buf_recv)); } close(fd_recv); exit(1); } close(fd_recv);//发送信息 while(memset(buf_send,0,sizeof(buf_send)),fgets(buf_send,1024,stdin)!=NULL){ write(fd_send,buf_send,strlen(buf_send)); } close(fd_send); wait(NULL); }