[英]Reading a named pipe while multiple processes are writing to it
What kind of a way is correct for solving this problem? 什么样的方法才是解决该问题的正确方法?
For example I have a program named write.c
that has 4 child processes and the child processes are write their PIDs to a single global named pipe. 例如,我有一个名为
write.c
的程序,该程序具有4个子进程,并且这些子进程将其PID写入单个全局命名管道。
Another program named read.c
should read this PIDs. 另一个名为
read.c
程序应读取此PID。
I have an approach like in below, but that approach has some problems.It can not read all PIDs, sometimes 3 of them and sometimes 2 of them.I think there is a synchronization problem , how can I solve this problem? 我有一种类似下面的方法,但是这种方法存在一些问题。它无法读取所有PID,有时无法读取其中的3个,有时甚至可以读取其中的2个。 :
:
writer.c
: writer.c
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(){
int fd;
char * myfifo = "/tmp/myfifo"; //FIFO file
char buffer[50];
mkfifo(myfifo, 0666); //creating the FIFO
for(int i=0;i<4;i++){ //creating 4 child process
if(fork() == 0) {
fd = open(myfifo, O_WRONLY); //each child process opens the FIFO for writing their own PID.
sprintf(buffer, "%d", getpid()); //each child process gets pid and assign it to buffer
printf("write:%s\n", buffer); // each child process prints to see the buffer clearly
write(fd, buffer, strlen(buffer)+1); //each child process writes the buffer to the FIFO
close(fd);
exit(0);
}
}
for(int i=0;i<4;i++) { //waiting the termination of all 4 child processes.
wait(NULL);
}
//parent area
}
reader.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char **argv) {
int fd1;
// FIFO file path
char * myfifo = "/tmp/myfifo";
// Creating the named file(FIFO)
mkfifo(myfifo, 0666);
char str1[80]; //str2[80];
while (1)
{
// First open in read only and read
fd1 = open(myfifo,O_RDONLY);
read(fd1, str1, 80);
// Print the read string and close
printf("read: %s\n", str1);
close(fd1);
}
}
This line writes the null byte into the fifo: 这行将空字节写入fifo:
write(fd, buffer, strlen(buffer)+1);
as a result if you have two pids in the pipe you'll read the following string: 因此,如果管道中有两个pid,则会读取以下字符串:
1234\02345\0
And the printf
will print only till the first \\0
: 并且
printf
将只打印到第一个\\0
为止:
1234
To fix it, it's easier to transfer the PID as binary rather than formatting and parsing text: 要解决此问题,将PID转换为二进制文件而不是格式化和解析文本会更容易:
if(fork() == 0) {
fd = open(myfifo, O_WRONLY);
pid_t pid = getpid();
write(fd, &pid, sizeof(pid));
close(fd);
exit(0);
}
fd1 = open(myfifo,O_RDONLY);
pid_t pid;
while (1) // whatever is your termination condition
{
read(fd1, &pid, sizeof(pid));
printf("read: %d\n", pid);
}
close(fd1);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.