我对Linux上的C ++中的命名管道有疑问。我有三个应用程序。我经营所有这些。每个应用程序必须将他的PID写入名为" first"," second"或者"第三个"。然后,应用程序读取其他两个通道的内容并将其显示在屏幕上。
FIRST app的输出示例:
"#1 pid - 2000" //他的PID
" Readed#2 pid - 3000" //其他人的PID
" Readed#3 pid - 5000" //其他人的PID
FIRST app的输出示例: "#2 pid - 3000" " Readed#1 pid - 2000" " Readed#3 pid - 5000"
所有应用都包含类似的代码(第一个应用):
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc, char* argv[])
{
char s1[15],s2[15],s3[15] ;
int fd1,fd2,fd3;
unlink("first") ;
if(mkfifo("first", S_IFIFO|0666)==-1)
{
fprintf(stderr, "Error creating first\n");
exit(0);
}
if(fd1=open("first",O_WRONLY)==-1)
{
fprintf(stderr, "Error opening first\n");
exit(0);
}
sprintf(s1,"#1 pid=%d", getpid());
write(fd1,&s1,sizeof(s1)) ;
printf("#1 pid=%d", getpid());
if(fd2=open("second",O_RDONLY|O_NONBLOCK)==-1)
{
fprintf(stderr, "Error opening second\n");
exit(0);
}
else
{
if(read(fd2, &s2, 15)==-1)
fprintf(stderr, "Error reading second\n");
else
fprintf(stdout,"\nReaded - #2 pid - %s", s2);
}
if(fd3=open("third",O_RDONLY|O_NONBLOCK)==-1)
{
fprintf(stderr, "Error opening third\n");
exit(0);
}
else
{
if(read(fd3, &s3, 15)==-1)
fprintf(stderr, "Error reading third\n");
else
fprintf(stdout,"\nReaded - #3 pid - %s", s3);
}
close(fd1) ; close(fd2); close(fd3);
return 1 ;
}
但我没有输出!当我运行第一个应用程序时,我希望看到类似的东西&#34;#1 pid是1000&#34;,但什么都没有。当我运行第二个应用程序时,我希望看到#34;#2 pis是2000&#34;并且在第一个应用程序中必须附加&#34;#2 pid是2000&#34;。所有应用的输出都是空的!哪里出错?感谢
答案 0 :(得分:1)
你应该为所有三个进程提供一个程序,它需要3个参数。为了论证,第一个参数是进程应该创建的FIFO,另外两个是它应该读取的FIFO。然后你可以运行:
./your_prog first second third &
./your_prog second third first &
./your_prog third first second &
但是,如果你喜欢保持三个几乎相同的程序而不是一个程序的想法,那那就是你的问题,而不是我的问题。
另外,当代码是纯C代码时,为什么这个问题被标记为'C ++'?
您确实需要将PID写入两次,以便其他两个进程中的每一个都可以读取它。
您需要修复文件描述符上的测试。您的代码如下:
if(fd2=open("second",O_RDONLY|O_NONBLOCK)==-1)
应该是:
if ((fd2 = open("second", O_RDONLY|O_NONBLOCK)) == -1)
目前,您正在为文件描述符分配0或1,因为编译器将其视为您编写的内容:
if (fd2 = (open("second", O_RDONLY|O_NONBLOCK) == -1))
然后你就会遇到计时问题。 read()
调用是非阻塞的(因为您使用O_NONBLOCK打开了FIFO),因此当没有数据准备好读取时,它们返回-1,errno
设置为EAGAIN
。也许你应该在文件打开后将模式更改为阻塞(一对fcntl()
调用,IIRC),或者你需要循环直到你读取一些输入,最好在循环中有一个亚秒延迟,或者您可以使用poll()
或select()
等待输入(但要小心:O_NONBLOCK可能会将其搞砸)。