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