Linux进程间通信之有名管道通信
摘要:因为无名管道的局限性,所以产生了有名管道。
1、什么叫有名管道?(fist in fist out)
首先它是一个文件,文件类型为p,创建方法为 mkfifo log.txt 。进程间通过文件IO 来write()或者read(),来操作管道文件。管道文件不能移动。
2、有名管道的特点
只要能访问管道文件的所有进程之间都可以通过该管道文件通信,严格遵循先进先出。
3、有名管道的创建
//终端:
mkfifo filename//
文件内,需要包含库:
#include"sys/types.h"
#include"sys/stat.h"
//使用以下函数创建,创建成功返回0 ,否则返回-1 并置error
int mkfifo(const char *pathname,mode_t mode);
//pathname 是需要创建的管道文件的文件名,mode 是指定管道FIFO 的权限,为三位8进制数
//例如下,创建有名管道文件,规避文件已存在的错误
if((mkfifo(argv[1],0666)<0)&& errno!=EEXIST)//EEXIST 通过man errno ,在错
{ //误码中表示file exists 文件已存在
perror("Fail to mkfifo");
return -1;
}
4、小试牛刀
write_fifo.c
#include"stdio.h"
#include"string.h"
#include"unistd.h"//
#include <sys/types.h>//下面三行是open的头文件
#include <sys/stat.h>
#include <fcntl.h>
#include"errno.h"
void write_file(int fd)
{
char buf[100]={0};
while(1)
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
write(fd,buf,strlen(buf));
if(strncmp(buf,"quit",4)==0)
{
break;
}
}
return ;
}
int main(int argc, const char *argv[])
{
int fd,n;
if(argc!=2)
{
fprintf(stderr,"usage:%s log.txt",argv[0]);
return -1;
}
if((mkfifo(argv[1],0666))&&errno!=EEXIST)
{
perror("Fail to mkfifo");
return -1;
}
fd=open(argv[1],O_WRONLY);
if(fd<0)
{
perror("Fail to open");
return -1;
}
write_file(fd);
close(fd);
return 0;
}
read_fifo.c
#include"stdio.h"
#include"string.h"
#include"unistd.h"
#include <sys/types.h>//下面三行是open的頭文件
#include <sys/stat.h>
#include <fcntl.h>
#include"errno.h"
void read_file(int fd)
{
char buf[100]={0};
int n;
while(1)
{
memset(buf,0,sizeof(buf));
n=read(fd,buf,sizeof(buf));
if(strncmp(buf,"quit",4)==0)
{
break;
}
printf("read:%s bytes:%d\n",buf,n);
}
return ;
}
int main(int argc, const char *argv[])
{
int fd,n;
if(argc!=2)
{
fprintf(stderr,"usage:%s log.txt",argv[0]);
return -1;
}
if((mkfifo(argv[1],0666))&&errno!=EEXIST)
{
perror("Fail to mkfifo");
return -1;
}
fd=open(argv[1],O_RDONLY);
if(fd<0)
{
perror("Fail to open");
return -1;
}
read_file(fd);
close(fd);
return 0;
}