进程通信之管道通信

来源:互联网 发布:淘宝手机端的收藏链接 编辑:程序博客网 时间:2024/05/22 14:57

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">管道通信:方式分为无名管道和有名管道。无名管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制。</span>

  管道是Linux支持的最初UNIX IPC形式之一,具有以下特点:

  1.管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道。

  2.只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)

  3.单独构成一种独立的文件系统。管道对于管道两端的进程而言,就是一个文件,但他不是普通的文件,不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在于内存中。

  4.数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。


函数部分:

pipe函数:建立管道

原型:int pipe(int fields[2])

参数说明:fields[0]是管道的读取端,fields[1]为管道的写入端

返回值:成功则返回0,否则返回-1

mkfifo函数:创建有名管道

原型: int mkfifo(const char * pathname,mode_t_mode)

参数:根据pathname建立特殊的FIFO文件,该文件必须不存在。mode为该文件的权限,当使用O_NONBLOCK旗标时,打开FIFO文件会立马返回,但是若还没有其他进程打开FIFO文件来读取,则写入的操作会立马返回ENXIO错误代码,O_RDONLY 只读  O_WRONLY 只写 O_RDWR 读写

返回值:成功返回0,否则返回-1

fifo_write.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/tmp/myfifo"


main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;

/*打开管道*/
fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);

if(argc==1)
{
printf("Please send something\n");
exit(-1);
}

strcpy(w_buf,argv[1]);

/* 向管道写入数据 */
if((nwrite=write(fd,w_buf,100))==-1)
{
printf("The FIFO has not been read yet.Please try later\n");
}
else 
printf("write %s to the FIFO\n",w_buf);
}


fifo_read.c

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define FIFO "/tmp/myfifo"


main(int argc,char** argv)
{
char buf_r[100];
int  fd;
int  nread;

/* 创建管道 */
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
printf("cannot create fifoserver\n");

printf("Preparing for reading bytes...\n");

memset(buf_r,0,sizeof(buf_r));

/* 打开管道 */
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));

if((nread=read(fd,buf_r,100))==-1)
{
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
pause(); /*暂停,等待信号*/
unlink(FIFO); //删除文件
}

在虚拟机中开启两个中断,分别运行read和write,可以实现管道通信。

1 0