【问题标题】:Using pipes to read to read and write.The program compiles but no output.Why?使用管道读取读写。程序编译但没有输出。为什么?
【发布时间】:2013-05-01 12:00:59
【问题描述】:

我正在尝试使用 pipes 从父进程内部使用 write() 写入一个字符串。然后生成一个子进程,我在其中读取它,计算字数并写回字数。然后让父进程打印字数。 我想出了这个:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include<sys/wait.h>    
int main(void)
{
int  fd[2], nbytes,status,i,count=0;
pid_t   PID;
char    string[] = "Hello, world\n";
char    readbuffer[80];
pipe(fd);
close(fd[0]);
write(fd[1], string, (strlen(string)+1));

if((PID=fork())<0)
{
    printf("Error\n");
    _exit(0);
}
else if(PID==0)
{

    close(fd[1]);
    nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
    for(i=0;readbuffer[i]!='\0';i++)
    {
        if(readbuffer[i]==' ')
        count++;
    }   
    //open(fd[1]);
    close(fd[0]);
    write(fd[1],&count,1);
    printf("The word count is %d ",count);
    //open(fd[0]);
}
else
{
    wait(&status);
    if(WIFEXITED(status))
{
    close(fd[1]);
    nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
    printf("The word count is %d ",nbytes);
    //open(fd[1]);
}
else
{
    printf("Error\n");
    _exit(0);
}
}
return(0);
}

这可以编译,但我没有得到任何输出。有人可以帮忙吗?

【问题讨论】:

  • 在尝试两个之前,您是否尝试在一个方向使用管道?

标签: c unix process pipe


【解决方案1】:

我无法尝试该代码,但看起来您正在关闭子进程中的两个管道端。您使用 fd[1] 进行写入,但它已关闭(在读取之前)。

我没有机会编译和尝试这段代码,所以以它为例,可能会解决问题。这个例子展示了如何使用两个单向管道将数据从父进程发送到子进程以及从子进程发送到父进程。

int main(void)
{
        int     fd1[2], fd2[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd1);
        pipe(fd2);


        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe fd1 */
                close(fd1[0]);
               /* Child process closes up output side of pipe fd2 */
                close(fd2[1]);

                /* Send "string" through the output side of pipe */
                write(fd1[1], string, (strlen(string)+1));
                /* Read in a string from the pipe */
                nbytes = read(fd2[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe fd1 */
                close(fd1[1]);
                /* Parent process closes up input side of pipe fd2 */
                close(fd2[0]);

                /* Read in a string from the pipe */
                nbytes = read(fd1[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
                /* Send "string" through the output side of pipe */
                write(fd2[1], string, (strlen(string)+1));
        }

        return(0);
}

【讨论】:

  • 您正在使用管道进行双向通信。通常,当您进行单向通信时,管道写入和读取端是关闭的。这是因为一个进程被期望写入而另一个进程被读取。在这种情况下,您有两个进程向/从同一管道写入和读取。解决方案是使用两个不同的单向管道,一个用于从父级到子级的通信,另一个用于从子级到父级的通信。
【解决方案2】:

我们必须打开管道的读取端,然后才能将数据写入管道,否则会有一个信号叫SIGPIPE 发生,
SIGPIPE 所做的是,它是一个同步信号,当客户端进程无法再写入管道时,它会接收到该信号。此信号执行的默认操作是终止进程。该信号只能发送到与套接字关联的进程,而不能发送到套接字的进程组。为了避免异常终止,进程需要捕获信号并处理它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    相关资源
    最近更新 更多