有名管道
# 有名管道
有名管道(FIFO)存在于文件系统中,功能比无名管道强大,可以让无关联的进程交换数据。
# 有名管道创建函数
有名管道创建函数为mkfifo(与shell命令同名)。执行成功返回0,否则返回-1,并设置errno。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode)
1
2
3
2
3
# 代码示例
// newfifo.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
mode_t mode = 0666;
if(argc != 2) {
puts("USAGE: newfifo {name}");
exit(EXIT_FAILURE);
}
if((mkfifo(argv[1], mode)) < 0) {
perror("mkfifo");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# FIFO操作函数
- 打开FIFO管道:open
- 关闭FIFO管道:close
- 读取FIFO管道:read
- 写入FIFO管道:write
# 代码示例
# 有名管道的读程序
// readfifo.c
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
int main(void)
{
int fd; /* Descriptor for FIFO */
int len; /* Bytes read from FIFO */
char buf[PIPE_BUF];
mode_t mode = 0666;
if((mkfifo("fifo1", mode)) < 0) {
perror("mkfifo");
exit(EXIT_FAILURE);
}
/* Open the FIFO read-only */
if((fd = open("fifo1", O_RDONLY)) < 0) {
perror("open");
exit(EXIT_FAILURE);
}
/* Read and display the FIFO's output until EOF */
while((len = read(fd, buf, PIPE_BUF - 1)) > 0)
printf("rdfifo read: %s", buf);
close(fd);
exit(EXIT_SUCCESS);
}
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
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
# 有名管道的写程序
/*
* wrfifo.c - Write to a "well-known" FIFO
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <time.h>
int main(void)
{
int fd; /* Descriptor for FIFO */
int len; /* Bytes written to FIFO */
char buf[PIPE_BUF]; /* Ensure atomic writes */
time_t tp; /* For time call */
/* Identify myself */
printf("I am %d\n", getpid());
/* Open the FIFO write-only */
if((fd = open("fifo1", O_WRONLY)) < 0) {
perror("open");
exit(EXIT_FAILURE);
}
/* Generate some data to write */
while(1) {
/* Get the current time */
time(&tp);
/* Create the string to write */
len = sprintf(buf, "wrfifo %d sends %s", getpid(), ctime(&tp));
/*
* Use (len + 1) because sprintf does not count
* the terminating null
*/
if((write(fd, buf, len + 1)) < 0) {
perror("write");
close(fd);
exit(EXIT_FAILURE);
}
sleep(3);
}
close(fd);
exit(EXIT_SUCCESS);
}
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
49
50
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
49
50
# 输出
# 终端1
$ ./readfifo
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:37 2023
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:40 2023
rdfifo read: wrfifo 3591 sends Wed Feb 22 20:40:43 2023
#终端2
$ ./writefifo
I am 3591
^C
$ ls
fifo1 readfifo writefifo
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 分析
readfifo中创建一个命名管道名为fifo1,打开并阻塞读取管道内容,直到有其它进程向管道中写入内容。
writefifo中打开管道fifo1,循环向其中写入进程号和当前时间信息。
编辑 (opens new window)
上次更新: 2023/03/31, 22:34:04
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05