1 创建有名管道
//come from /user/include/sys/stat.h
extern int mkfifo (_const char *_path,_mode_t _mode);
mkfifo()会根据参数来创建特殊的有名管道文件,
该文件要求必须不存在,而且参数mode为该文件的权限,mkfifo()创建的FIFO文件的其他进程都可以用读写一般文件的方式存取。如果该函数执行成功将返回0,否则返回-1,失败原因将存储于errno中。
2 读写有名管道
//come from /user/include/unistd.h
extern ssize_t read (int _fd,void *_buf,size_t _nbytes);
extern ssize_t write (int _fd,_const void *_buf,size_t _n);
如果希望打开管道写端,则需要另一个进程打开管道读端,整个程序才能正常进行;如果只打开有名管道的一端,则系统将暂时阻塞打开进程,直到有另一个进程打开该管道的另一端,当前进程才会继续执行。3 例子
非父子进程采用有名管道通信实例:
向有名管道中发送数据的进程源代码如下:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>
#define FIFO_NAME "/home/crosslandy/Linux/PIPE/my_fifo"
int main(int argc,char *argv[])
{
int pipe_fd;
int res;
char buffer[]="Hello world!";
if(access(FIFO_NAME,F_OK)==-1) //文件是否存在
{
res=mkfifo(FIFO_NAME,0766);
if(res!=0)
{
fprintf(stderr,"Could not creat fifo %s\n",FIFO_NAME);
exit(1);
}
}
printf("Process %d opening FIFO O_WRONLY\n",getpid());
pipe_fd=open(FIFO_NAME,O_WRONLY);
printf("the file`s descriptor is %d\n",pipe_fd);
if(pipe_fd!=-1)
{
res=write(pipe_fd,buffer,sizeof(buffer)); // 写书据
printf("write data is %s,%d bytes is writen\n",buffer,res);
(void)close(pipe_fd); //切记关闭文件描述符
}
else
exit(1);
printf("Process %d finished\n",getpid());
exit(1);
}
读进程负责从有名管道中读取数据,其源代码如下:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>
#define FIFO_NAME "/home/crosslandy/Linux/PIPE/my_fifo"
int main(int argc,char *argv[])
{
int pipe_fd;
int res;
char buffer[4096];
int bytes_read=0;
memset(buffer,'\0',sizeof(buffer));
printf("Process %d opening FIFO O_RDONLY\n",getpid());
pipe_fd=open(FIFO_NAME,O_RDONLY);
printf("the file`s descriptor is %d\n",pipe_fd);
if(pipe_fd!=-1)
{
bytes_read=read(pipe_fd,buffer,sizeof(buffer));
printf("the read data is %s\n",buffer);
close(pipe_fd); //不解释
}
else
exit(1);
printf("Process %d finished,%d bytes read\n",getpid(),bytes_read);
exit(1);
}
编译运行如下:
首先编译写过程:如下
[crosslandy@localhost PIPE]$ gcc -o fifo_write fifo_write.c
[crosslandy@localhost PIPE]$ ./fifo_write
Process 4182 opening FIFO O_WRONLY
可见无法继续执行下去,此时另外打开一个终端,编译读过程并运行则在此终端下显示如下:
[crosslandy@localhost PIPE]$ gcc -o fifo_read fifo_read.c
[crosslandy@localhost PIPE]$ ./fifo_read
Process 4771 opening FIFO O_RDONLY
the file`s descriptor is 3
the read data is Hello world!
Process 4771 finished,13 bytes read
并且在此终端显示出结果的同时,执行写进程的终端显示发生变化如下:
[crosslandy@localhost PIPE]$ gcc -o fifo_write fifo_write.c
[crosslandy@localhost PIPE]$ ./fifo_write
Process 4182 opening FIFO O_WRONLY
the file`s descriptor is 3
write data is Hello world!,13 bytes is writen
Process 4182 finished
可见读写进程需要同时进行才能完成有名管道的通信。