mkfifo
现在先通过这段命令来创建一个FIFO文件
mkfifo fifo
接着我们会发现目录下出现了这个文件
开始的"p"代表"fifo"是一个管道文件,接下来我们创建两个进程,一个向fifo写数据,另一个从fifo读数据
命名管道
进程间的通信根本就是要让不同的进程看到同一份资源,而匿名管道利用的是子进程继承父进程资源的特性,让他们看到同一份资源。那么在没有血缘关系的进程间这种方式就行不通了。那么在这样的情况下我们可以使用命名管道进行进程间通信
命名管道与匿名管道的区别
1.匿名管道由pipe函数创建并打开 2.命名管道由mkfifo函数创建,打开用open 3.FIFO与pipe之间唯一的区别在于它们创建和打开的方式不同,一旦这些工作完成之后,它们具有相同的语义
命名管道实现进程间通信示例
在同一个目录下我们分别创建server.c和client.c(同时编译两个文件的操作见"如何让Makefile编译多个文件")文件,分别代表服务端和客户端,我们希望客户端向fifo写入数据,客户端接收数据并做出反馈
client.c
int main()
4 {
5 int fd = open(MY_FIFO, O_WRONLY);
6 if (fd < 0)
7 {
8 perror("open");
9 return 1;
10 }
11 while (1)
12 {
13 char buffer[64] = { 0 };
14 printf("input: ");
15 fflush(stdout);
16 ssize_t s = read(0, buffer, sizeof(buffer) - 1);
17 if (s > 0)
18 {
19 buffer[s - 1] = 0;
20
21 write(fd, buffer, strlen(buffer));
22 }
23
24 }
25 return 0;
26 }
server.c
2 int main()
3 {
4 umask(0);
5 if (mkfifo(MY_FIFO,0666 ) < 0)
6 {
7 perror("mkfifo");
8 return 1;
9 }
10 int fd = open(MY_FIFO, O_RDONLY);
11 if (fd < 0)
12 {
13 perror("open");
14 return 2;
15 }
16
17 while (1)
18 {
19 char buffer[64] = { 0 };
20 ssize_t s = read(fd, buffer, sizeof(buffer) - 1);
21 if (s > 0)
22 {
23 buffer[s] = 0;
24 if (strcmp(buffer, "show") == 0)
25 {
26 if (fork() == 0)
27 {
28 execl("/usr/bin/ls", "ls", "-l", NULL);
29 }
30 waitpid(-1, NULL, 0);
31 }
else if (strcmp(buffer, "train") == 0)
35 {
36 execl("/usr/bin/sl", "sl", NULL);
37 }
38 else
39 {
40 printf("client: %s\n", buffer);
41 }
42 }
43 else if (s == 0)
44 {
45 printf("client quit\n");
46 break;
47 }
48 else
49 {
50 perror("read");
51 break;
52 }
53 }
54
55 close(fd);
56 return 0;
57 }
如何让Makefile编译多个文件
我们可以先写一个伪文件all,并指明all需要依靠client和server文件,之后在写client和server需要的操作,具体Makefile如下
.PHONY:all
all:client server
client:client.c
gcc -o $@ $^
server:server.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f client server fifo
|