应用程序中的空输出与命名管道

时间:2014-05-01 13:18:53

标签: c++ linux pipe

我对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;。所有应用的输出都是空的!哪里出错?感谢

1 个答案:

答案 0 :(得分:1)

注释

你应该为所有三个进程提供一个程序,它需要3个参数。为了论证,第一个参数是进程应该创建的FIFO,另外两个是它应该读取的FIFO。然后你可以运行:

./your_prog first second third &
./your_prog second third first &
./your_prog third first second &

但是,如果你喜欢保持三个几乎相同的程序而不是一个程序的想法,那那就是你的问题,而不是我的问题。

另外,当代码是纯C代码时,为什么这个问题被标记为'C ++'?

错误

  1. 您确实需要将PID写入两次,以便其他两个进程中的每一个都可以读取它。

  2. 您需要修复文件描述符上的测试。您的代码如下:

    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))
    
  3. 然后你就会遇到计时问题。 read()调用是非阻塞的(因为您使用O_NONBLOCK打开了FIFO),因此当没有数据准备好读取时,它们返回-1,errno设置为EAGAIN。也许你应该在文件打开后将模式更改为阻塞(一对fcntl()调用,IIRC),或者你需要循环直到你读取一些输入,最好在循环中有一个亚秒延迟,或者您可以使用poll()select()等待输入(但要小心:O_NONBLOCK可能会将其搞砸)。