Linux进程通信——使用有名管道

无名管道只能用于父子进程通信,而有名管道可以用于任意进程间通信。
头文件:

#include <sys/types.h>

#include <sys/stat.h>

函数:
int mkfifo(const char *filename, mode_t mode);
创建有名管道对应的实名文件,该文件必须事先不存在。
返回0代表创建成功,否则返回-1。
filename:文件路径
mode:文件权限

创建成功之后可以像操作普通文件一样使用read、write进行读写操作。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**************************************
*
* 使用有名管道进行进程通信——写进程
* 文件名:fifo_write.c
* 龙昌博客:http://www.xefan.com
*
**************************************/

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

#define FIFO "/tmp/myfifo"

int main(int argc, char *argv[])
{
int fd;
char buf[100];
int num;

unlink(FIFO); //先删除文件
//创建有名管道
if ( (mkfifo(FIFO, O_CREAT|O_EXCL|O_RDWR) < 0) && (errno != EEXIST))
{
perror("mkfifo");
}

fd = open(FIFO, O_WRONLY);
if (fd < 0)
{
perror("open");
exit(1);
}
while (1)
{
scanf("%s", buf);
if ((num=write(fd, buf, 100)) < 0)
{
if(errno == EAGAIN)
{
printf("FIFO has not been read yet.\n");
}
}
}
close(fd);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**************************************
*
* 使用有名管道进行进程通信——读进程
* 文件名:fifo_read.c
* 龙昌博客:http://www.xefan.com
*
**************************************/
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>

#define FIFO "/tmp/myfifo"

int main(int argc, char *argv[])
{
int fd;
int num;
char buf[100];

//打开管道文件
//fd = open(FIFO, O_RDONLY|O_NONBLOCK); //非阻塞方式打开
fd = open(FIFO, O_RDONLY);
if (fd < 0)
{
perror("open");
exit(1);
}
while (1)
{
memset(buf, 0, sizeof(buf));
if ((num=read(fd, buf, 100)) < 0)
{
if (errno == EAGAIN)
{
printf("no data yet\n");
}
sleep(1);
continue;
}
printf("read %s from FIFO\n", buf);
sleep(1);
}
return 0;
}

先运行写进程再运行读进程