C 如何使服务器进程等待FIFO的第二次读取()?
我的服务器和客户端使用C语言中的两个命名管道(fifo)来回通信,直到服务器收到C 如何使服务器进程等待FIFO的第二次读取()?,c,write,mkfifo,C,Write,Mkfifo,我的服务器和客户端使用C语言中的两个命名管道(fifo)来回通信,直到服务器收到exit消息。 显然,服务器端在第二次尝试从其FIFO读取()时会阻塞,尽管客户端已成功写入。我认为问题在于服务器尝试read()的速度比客户端能够write()的速度要快 这是服务器: #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include &quo
exit
消息。
显然,服务器端在第二次尝试从其FIFO读取()时会阻塞,尽管客户端已成功写入。我认为问题在于服务器尝试read()
的速度比客户端能够write()
的速度要快
这是服务器:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "header.h"
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
//fifo for the server to read from
if (mkfifo(FIFONAME, S_IFIFO|0666) < 0) {
if (errno != EEXIST) {
perror("Error with mkfifo");
exit(1);
}
}
int f;
if ((f = open(FIFONAME, O_RDONLY)) < 0) {
perror("Error with open");
exit(1);
}
Message msg;
while(1) {
if ((read(f, &msg, sizeof(Message))) > 0) {
if (strcmp(msg.user, "exit") == 0) {
close(f);
unlink(FIFONAME);
exit(0);
}
if (strcmp(msg.user, "new client") == 0) {
switch (fork()) {
case -1:{
perror("Error with fork");
exit(1);
}
case 0:{
char gender[MAXLEN];
char client_fifo[30];
sprintf(msg.user, "I need client's gender\n");
sprintf(client_fifo, "fifo_%d", msg.pid);
msg.pid = getpid();
int o;
//open client's fifo for server to write to
if ((o = open(client_fifo, O_WRONLY)) == -1) {
perror("Error opening client fifo");
exit(1);
}
//send message
write(o, &msg, sizeof(Message));
//read client's answer, but program blocks here
if ((read(f, &msg, sizeof(Message))) > 0) {
sprintf(gender,"%s", msg.user);
printf("Client's gender is %s\n", gender);
}
close(o);
exit(0);
}
}
}
}
}
return 0;
}
我需要像这样写更多的来回消息,但我不知道如何让服务器在第二次调用
read()
时不阻塞。在父进程和子进程中,服务器中都有相互竞争的read
调用。在fork
之后,两个进程都将竞相执行read
调用以获取数据。在客户端写操作之后先运行的哪个进程将获胜,而另一个进程将阻塞。@kaylum我需要分叉,以便在不同的进程中并行地为连接到服务器的每个客户端提供服务。fork
之后的read
应该只被子进程看到,这就是我使用用例的原因。你理解我的第一条评论吗?父进程和子进程都调用read
,因此它们将争夺相同的数据。只有一个fifo,从一个进程读取它将导致另一个进程无法获取数据,从而阻塞。“fork后读取”是一个模棱两可的短语,因为fork后有多个读取。在fork之后,有两个进程正在执行,其中一个在while循环中,以read
开头,而read
发生在fork之后。让家长等待。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "header.h"
#include <unistd.h>
int f,fc;
char fifoname[20];
Message msg;
int main(int argc, char* argv[]) {
sprintf(fifoname, "fifo_%d", getpid());
if (mkfifo(fifoname, S_IFIFO | 0666) < 0) {
perror("Error with client's fifo");
printf("Could not create fifo_%d", getpid());
exit(1);
}
if ((f=open(FIFONAME,O_WRONLY))<0) {
perror("Error connecting to server");
exit(2);
}
char gender[MAXLEN];
strcpy(msg.user, "new client");
msg.pid = getpid();
//first message to server
write(f, &msg, sizeof(msg));
char arg[MAXLEN];
if (argc > 1) {
strcpy(arg, argv[1]);
} else {
strcpy(arg, "work");
}
if (strcmp(arg, "exit")) {
if ((fc = open(fifoname, O_RDONLY))<0) {
perror("Error opening client's fifo");
printf("Could not open my fifo");
exit(3);
}
if (read(fc, &msg, sizeof(msg)) > 0) {
printf("%s\n",msg.user);
}
scanf("%s", gender);
strcpy(msg.user, gender);
msg.pid = getpid();
printf("writing gender...\n");
write(f, &msg, sizeof(msg));
//program successfully reaches this print:
printf("gender written\n");
close(fc);
}
unlink(fifoname);
close(f);
exit(0);
}
#define MAXLEN 20
typedef struct {
int pid;
char user[MAXLEN];
} Message;
#define FIFONAME "fifo_server"