Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 子进程和父进程之间的管道()_C_Operating System - Fatal编程技术网

C 子进程和父进程之间的管道()

C 子进程和父进程之间的管道(),c,operating-system,C,Operating System,我为子进程和父进程之间的管道()编写了以下代码。我需要确保这是否是正确的代码。顺便说一句,它给出了我们应该看到的答案 #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 = for

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

#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;

}
#包括
#包括
#包括
int main(int argc,char*argv[]){
pid_t pid;
int-fd[2];
char-buf[20];
管道(fd);
开关(pid=fork()){
案例1:
佩罗(“管道”);
出口(1);
案例0:
/*子进程*/
关闭(fd[1]);
读取(fd[0],buf,20);
printf(“子级读取来自父级的消息:%s\n”,buf);
出口(1);
打破
违约:
/*父进程*/
关闭(fd[0]);
写入(fd[1],“来自家长的问候”,17);
打破
} 
返回0;
}

虽然不需要
pid
变量,但
开关
语句基本正常

父代码也基本正常,但字符串实际上是18字节(不带NUL终止符),19字节(带NUL终止符)。在子对象中处理换行符和NUL终止符是一种很好的做法,因此我会坚持使用17并从字符串中删除换行符

子代码是错误的。您需要一个变量来存储
read
的返回值。您需要检查返回值以确保读取成功。您需要在字符串中添加NUL终止符。在C编程语言中,“字符串”是以零字节结尾的字符数组(称为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;
}
#包括
#包括
#包括
#包括
内部主(空)
{
int-fd[2];
字符缓冲区[20];
如果(管道(fd)<0){
佩罗(“管道”);
出口(1);
}
开关(fork()){
案例1:
佩罗尔(“福克”);
出口(1);
案例0:
/*子进程*/
关闭(fd[1]);
ssize_t count=读取(fd[0],缓冲区,sizeof(缓冲区)-1);

如果(这不是一个代码审查网站。你的问题是什么?实际上我需要验证是否有编写此类代码的最佳实践。我对这种操作系统的东西是绝对的初学者。我最好问一下。我忘记了空终止符。但我有一些事情要澄清。我想我已经检查了返回值以确保“读取”在开始处成功。如果“(管道(fd)<0){perror(“管道”);出口(1);}“@hasinisilva检查
pipe
的返回值会告诉您是否成功创建了管道。在正常情况下,如果创建管道成功,则
读取
应该成功。但无论如何,最好检查
读取
的返回值。例如,如果父级被
SIGSTO停止P
SIGKILL
在它发送消息之前,孩子的
读取将失败。现在我明白了。我误解了。无论如何,我很感激,你回答了我。我可以澄清这么多不确定的问题。另一个让人困惑的问题是“退出(1)”“。为什么我们总是使用“1”而不是其他数值。我试过使用0一次。代码执行得很顺利。@hasinisilva传递给exit的值在程序内部无效。但是,如果从shell脚本调用程序,则该值将返回到脚本。脚本可以执行不同的操作。”取决于您的程序是成功还是失败。通常,
exit(0)
表示程序成功,而任何其他值表示程序失败。实际上,我只是知道了它。我过去使用exit()时并不知道它背后的确切含义。很高兴有这样的帮助。谢谢@user3386109