tir*_*der 4 c ipc pipe named-pipes
我正在尝试通过命名管道使用 IPC 在两个进程之间创建非常基本的客户端服务器通信。
我有 2 个管道,即fifo_client和fifo_server
我有以下两个类fifoclient.c,并且fifoserver.c具有以下代码行来打开两个管道。
fifoclient.c
int client = open("fifo_client",O_WRONLY);
int server = open("fifo_server",O_RDONLY);
Run Code Online (Sandbox Code Playgroud)
fifoserver.c
int client = open("fifo_client",O_RDONLY);
int server = open("fifo_server",O_WRONLY);
Run Code Online (Sandbox Code Playgroud)
然而,只要简单地改变打开client和server管道的顺序fifoserver.c,程序就会冻结。
冻结时代码是这样写的:
fifoserver.c
int server = open("fifo_server",O_WRONLY);
int client = open("fifo_client",O_RDONLY);
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下server,管道先于管道打开client。这会导致程序不响应(可能是竞争条件?)。
有人可以解释发生了什么以及为什么吗?
编辑:
这是两个类的完整代码:
fifoserver.c
#define BUFSIZE 20
#include<stdio.h>
#include<fcntl.h>
int main()
{
char buf[BUFSIZE];
int client = open("fifo_client",O_RDONLY);
int server = open("fifo_server",O_WRONLY);
if( server<0 || client < 0)
{
printf("Couldn't open file\n");
exit(1);
}
read(client,buf,BUFSIZE*sizeof(char));
printf("Client Says: %s\n",buf);
write(server,"Fine, Thank You!",BUFSIZE*sizeof(char));
close(server);
close(client);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
fifoclient.c
#define BUFSIZE 20
#include<stdio.h>
#include<fcntl.h>
int main()
{
char buf[BUFSIZE];
int client = open("fifo_client",O_WRONLY);
int server = open("fifo_server",O_RDONLY);
if(client <0 || server <0)
{
printf("ERROR! Couldn't open file!\n");
exit(1);
}
write(client,"Hello! How are you?",BUFSIZE*sizeof(char));
read(server,buf,BUFSIZE*sizeof(char));
printf("Server Says: %s\n",buf);
close(server);
close(client);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从man 7 fifo:
内核为至少一个进程打开的每个 FIFO 特殊文件维护一个管道对象。必须先打开 FIFO 两端(读和写),然后才能传递数据。通常,打开 FIFO 会阻塞,直到另一端也打开为止。
换句话说,您的open()调用将阻塞,直到管道的另一端有进程为止。这不是竞争条件,而是死锁。如果进程不以相同的顺序打开管道,它们将永远相互等待。因此,正如您所注意到的,解决方案是它们必须以相同的顺序打开 fifo。