六、进程间通信-有名管道
命名管道
可用于没有亲缘关系的进程间进行数据传输,数据只能单向流动。
(1)创建管道
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *filename,mode_t mode)
-
filename:用户读写的FIFO文件名。
mode:模式及权限参数说明:
-
O_RDONLY:只读管道。
-
O_WRONLY:只写管道
-
O_RDWR:读写管道。
-
O_NONBLOCK:非阻塞。
-
O_CREAT:如果该fifo文件不存在,那么就创建一个新的文件,并用第三个参数为其设置权限。
-
O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误信息。这一参数可测试文件是否存在。
-
0:成功
-
EACCESS:参数filename所指定的目录路径五可执行的权限。
-
EEXIST:参数filename所指定的文件已存在。
-
ENAMETOOLONG:参数filename的路径名称太长。
-
ENOENT:参数filename包含的目录不存在。
-
ENOSPC:文件系统的剩余空间不足。
-
ENOTDIR:参数filename路径种的目录存在但却非真正的目录。
-
EROFS:参数filename指定的文件存在于只读文件系统内。
(2)特点
-
任意进程间数据传输
-
write和read操作可能会阻塞进程
-
write具有"原子性"
- 使用FIFO的过程中,当一个进程对管道进行读操作时:
-
若该管道是阻塞类型,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入。
-
若该管道是非阻塞类型,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,读函数将立即返回0.
-
- 使用FIFO的过程中,当一个进程对管道进行写操作时:
-
若该管道是阻塞类型,则写操作将一直阻塞到数据可以被写入。
-
若该管道是非阻塞类型而不能写入全部数据,则写操作进行部分写入或者调用失败。
-
(3)使用步骤
- 第一个进程mkfifo有名管道
- open有名管道,write/read数据
- close有名管道
- 第二个进程open有名管道,read/write数据
- close有名管道
(4)实例
子进程写数据到FIFO文件,父进程读取文件数据
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define MAX_BUFFER_SIZE PIPE_BUF /*大小为4096,定义在limits.h种*/
#define MYFIFO "myfifo"
void fifo_read(void)
{
char buff[MAX_BUFFER_SIZE];
int fd;
int nread;
printf("********************read fifo***********************\n");
if(access(MYFIFO,F_OK) == -1)
{
if((mkfifo(MYFIFO,0666) <0)&&(errno!=EEXIST))
{
printf("Cannot create FIFO file\n");
exit(1);
}
}
fd = open(MYFIFO,O_RDONLY);
if(fd == -1)
{
printf("open fifo file error\n");
exit(1);//exit(1)表示异常退出.这个1是返回给操作系统的,0表示正常退出。
}
memset(buff,0,MAX_BUFFER_SIZE);
if((nread = read(fd,buff,MAX_BUFFER_SIZE)) > 0)
{
printf("Read '%s' from FIFO\n",buff);
}
printf("********************close fifo******************************\n");
close(fd);
exit(0);
}
void fifo_write(void)
{
int fd;
char buff[] = "this is a fifo test demo";
int nwrite;
sleep(2); //等待子进程先运行
/*以只写阻塞方式打开FIFO管道*/
fd = open(MYFIFO,O_WRONLY|O_CREAT,0644);
if(fd == -1)
{
printf("Open fifo file error\n");
exit(1);
}
printf("Write '%s' to FIFO\n",buff);
/*向管道中写入字符串*/
nwrite = write(fd,buff,MAX_BUFFER_SIZE);
if(wait(NULL))//等待子进程退出
{
close(fd);
exit(0);
}
}
int main()
{
pid_t result;
result = fork();
if(result == -1)
{
printf("Fork error\n");
}
else if(result == 0) //子进程
{
fifo_read();
}
else //父进程
{
fifo_write();
}
return result;
}
执行结果:


浙公网安备 33010602011771号