我正在写一个代码,其中孩子和父母应该给彼此提供时间信息,接收者应该打印它。当我在父进程上找到时间并尝试在父进程上打印它工作正常。但是当我尝试要通过管道发送它,它会写一个带有奇怪问号和az字母的行。如果有人试图执行代码,我会注释最后一行。对凌乱的代码感到厌烦,但我无法在当前的键盘中修复它。
{5,10}
答案 0 :(得分:2)
您的问题是在创建管道之前进行fork
电话 。所以实际上你read
什么都不读,而你的printf
打印出分配了buffer
的堆栈上的垃圾。
这是您的代码已修复。我还在父母中添加了一个wait
调用,以避免儿童无处不在地打印到控制台:)
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
void formatted_time(char *sender_name,char *receiver_name, char output[]) {
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80, "%Y-%m-%d %H:%M:%S", nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv) {
char* parent="Parent";
char* child1="Child1";
char result[80];
char buffer[80];
int firstchild, secondchild, read1;
int mypipe[2];
if (pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
firstchild=fork();
if (firstchild == 0) { // first child
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1 = read(mypipe[0], buffer, sizeof(buffer));
printf("%d %s\n", read1, buffer);
} else {
secondchild=fork(); //Creating second child
if(secondchild == 0) { //2nd child
sleep(6);
} else { //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent, child1, result);
int w;
w = write(mypipe[1], result, strlen(result)+1);
printf("%d bytes written\n", w);
wait(NULL);
}
}
return 0;
}
答案 1 :(得分:1)
在创建管道之前,您正在分叉第一个孩子。因此,您创建了两个不同的管道:一个在父级中,另一个在子级中。之后,如果您从第一个子节点中创建的管道中读取,read
将返回0,表示尚未读取任何数据。因此,缓冲区中的数据无效,并且printf
被禁止。始终检查API调用的返回码!
用户“nsilent22”已经为您的代码提供了良好的清理。在末尾添加3个右括号}
以关闭所有块后,在创建管道后至少移动了分叉:
firstchild=fork();
if (firstchild == 0) { // first child
在读取调用时,您应该检查返回码:
read1=read(mypipe[0],buffer,sizeof(buffer));
if (read1 <= 0) {
printf("read failed with code %d\n, ", read1);
} else {
printf("%s\n",buffer);
}