相信自己,只有不想做的,没有做不到的。
分类: LINUX
2013-12-16 21:49:52
二 有名管道
特点:在文件系统中存在一个名字,管道存在于内核空间
A.创建有名管道
int mkfifo(char *filename,int mode)
例如:
//如果创建有名管道,是由于管道文件存在而失败
//,认为是正常的情况
if(mkfifo(filename,0666) < 0 && errno != EEXIST)
{
.....
}
B.打开有名管道文件
注意:
1.有名管道一端以只读的方式打开,此时会阻塞,直到另一端以写的方式打开
2.有名管道一端以只写的方式打开,此时会阻塞,直到另一端以读的方式打开
3.如果以读写方式打开,此时不阻塞
三 管道特性(无名管道和有名管道)
A.读管道
1. 写端存在
读管道,管道中有数据,读取数据;管道中没有数据,阻塞。
2.写端不存在
读管道,管道中有数据读取数据,管道中没有数据的时候,不会阻塞,read立即返回0
B.写管道
1.读端存在
写管道,管道空闲,写入数据,管道满,写阻塞
2.读端不存在
写管道,此时写操作没有意义,内核会向写管道的进程发送SIGPIPE信号,此信号默认操作是杀死进程
用创建进程的方式来实现两个进程交谈
在A.c中代码如下
#include
#include
#include
#include
#include
#include
#include
#include
#include
int read_fifo(const char *filename)
{
int n;
char buf[1024];
int fifo_fd;
//打开有名管道
if((fifo_fd = open(filename,O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));
}
printf("Open fifo success for readonly.\n");
//从管道中读取数据,并且打印,如果读"quit",结束进程
while(1)
{
//读管道
n = read(fifo_fd,buf,sizeof(buf) - 1);
buf[n] = '\0';
if(n == 0)
{
kill(getppid(),9);
break;
}
printf("Read %d bytes : %s.\n",n,buf);
}
return 0;
}
int write_fifo(const char *filename,int pid)
{
char buf[1024];
int fifo_fd;
//打开有名管道
if((fifo_fd = open(filename,O_WRONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));
}
while(1)
{
printf(">");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) - 1] = '\0';
//写管道
write(fifo_fd,buf,strlen(buf));
if(strncmp(buf,"quit",4) == 0)
{
kill(pid,9);
break;
}
}
return 0;
}
//./a.out FIFO1 FIFO2
int main(int argc, const char *argv[])
{
pid_t pid;
//创建有名管道文件
if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}
//创建有名管道文件
if(mkfifo(argv[2],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
read_fifo(argv[2]);
}
if(pid > 0)
{
write_fifo(argv[1],pid);
}
exit(EXIT_SUCCESS);
}
在B.c中代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
int read_fifo(const char *filename)
{
int n;
char buf[1024];
int fifo_fd;
//打开有名管道
if((fifo_fd = open(filename,O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));
}
printf("Open fifo success for readonly.\n");
//从管道中读取数据,并且打印,如果读"quit",结束进程
while(1)
{
//读管道
n = read(fifo_fd,buf,sizeof(buf) - 1);
buf[n] = '\0';
if(n == 0)
{
kill(getppid(),9);
break;
}
printf("Read %d bytes : %s.\n",n,buf);
}
return 0;
}
int write_fifo(const char *filename,int pid)
{
char buf[1024];
int fifo_fd;
//打开有名管道
if((fifo_fd = open(filename,O_WRONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));
}
while(1)
{
printf(">");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) - 1] = '\0';
//写管道
write(fifo_fd,buf,strlen(buf));
if(strncmp(buf,"quit",4) == 0)
{
kill(pid,9);
break;
}
}
return 0;
}
//./a.out FIFO1 FIFO2
int main(int argc, const char *argv[])
{
pid_t pid;
//创建有名管道文件
if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}
//创建有名管道文件
if(mkfifo(argv[2],0666) < 0 && errno != EEXIST)
{
fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
read_fifo(argv[1]);
}
if(pid > 0)
{
write_fifo(argv[2],pid);
}
exit(EXIT_SUCCESS);
}