【问题标题】:pipe() between child and parent process子进程和父进程之间的 pipe()
【发布时间】:2016-10-26 17:19:45
【问题描述】:

我为子进程和父进程之间的 pipe() 编写了这段代码。我需要确保这是否是正确的代码。顺便说一句,它给出了应该看到的答案!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>



int main(int argc, char *argv[]){
    pid_t pid;
    int fd[2];
    char buf[20];

pipe(fd);


switch(pid = fork()){

    case -1:
        perror("pipe");
        exit(1);

    case 0: 
        /*child process*/
        close(fd[1]);
        read(fd[0], buf, 20);
        printf("Child read message from parent: %s\n", buf);
        exit(1);
        break;

    default:
     /*parent process*/
        close(fd[0]);
        write(fd[1], "Hello from parent\n", 17);
        break;
    } 
    return 0;

}

【问题讨论】:

  • 这不是一个代码审查网站。你有什么问题?
  • 实际上我需要验证是否有任何最佳实践来编写此类代码。我是这个操作系统的绝对初学者。

标签: c operating-system


【解决方案1】:

switch 语句大部分都可以,尽管您不需要 pid 变量,因为您不使用它做任何事情。

父代码也大多没问题,但字符串实际上是 18 个字节没有 NUL 终止符,19 个字节有 NUL 终止符。在孩子中处理换行符和 NUL 终止符是一种很好的做法,所以我会坚持使用 17 并从字符串中删除换行符。

子代码错误。您需要一个变量来存储来自read 的返回值。您需要检查返回值以确保 read 成功。并且您需要在字符串中添加一个 NUL 终止符。在 C 编程语言中,"string" 是一个以零字节结尾的字符数组(称为 NUL 终止符,写作'\0')。您的工作是确保您使用的缓冲区总是足够大以容纳 NUL 终止符,并且每个字符串 具有 一个 NUL 终止符。

所以固定的代码是这样的:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main( void )
{
    int fd[2];
    char buffer[20];

    if ( pipe(fd) < 0 ) {
        perror( "pipe" );
        exit( 1 );
    }

    switch( fork() ) {
        case -1:
            perror( "fork" );
            exit( 1 );

        case 0:
            /*child process*/
            close(fd[1]);
            ssize_t count = read( fd[0], buffer, sizeof(buffer)-1 );
            if ( count <= 0 ) {
                perror( "read" );
                exit( 1 );
            }
            buffer[count] = '\0';
            printf( "Child read message from parent: %s\n", buffer );
            exit(1);

        default:
            /*parent process*/
            close(fd[0]);
            char *message = "Hello from parent";
            size_t length = strlen( message );
            write( fd[1], message, length );
            break;
    }

    return 0;
}

【讨论】:

  • 最好我问这个。我忘记了 NULL 终止符。但我有一点要澄清。我以为我已经检查了返回值以确保“读取”在开始时成功。如果'(管道(fd)
  • @hasinisilva 检查来自pipe 的返回值告诉您管道是否创建成功。在正常情况下,如果创建管道成功,那么read 应该会成功。但无论如何,最好检查来自read 的返回值。例如,如果父级在发送消息之前被SIGSTOPSIGKILL 停止,则子级中的read 将失败。
  • 现在我明白了。我误会了。无论如何,我很感激,你回答了我。我可以清除很多不确定的点。另一个令人困惑的事情是'exit(1)'。为什么我们总是使用“1”而不是其他数值。我尝试使用 0 一次。代码执行没有任何问题。
  • @hasinisilva 您传递给exit 的值在您的程序中无效。但是,如果您从 shell 脚本调用程序,则该值将返回给脚本。根据您的程序是成功还是失败,脚本可以采取不同的行动。通常exit(0)表示程序成功,其他任何值表示程序失败。
  • 其实我刚知道。我曾经使用 exit() 却不知道它背后的确切内容。能得到这样的帮助真是太好了。谢谢@user3386109
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 2018-05-25
  • 1970-01-01
  • 2013-10-12
  • 2019-06-17
  • 2015-04-12
  • 1970-01-01
相关资源
最近更新 更多