Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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/UNIX进程间通信使用管道发送字符串_C_Unix_Time_Pipe_Ipc - Fatal编程技术网

C/UNIX进程间通信使用管道发送字符串

C/UNIX进程间通信使用管道发送字符串,c,unix,time,pipe,ipc,C,Unix,Time,Pipe,Ipc,我正在编写一个代码,在这个代码中,孩子和家长应该互相提供时间信息,接收者应该打印出来。当我在家长进程上找到时间并尝试在家长进程上打印时,它工作正常。但当我尝试通过管道发送时,它会写一行奇怪的问号和z字母。我对最后一行进行了注释,以防有人试图执行代码。抱歉,代码太乱了,但我无法在当前键盘上修复它 #include<stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/time.h&

我正在编写一个代码,在这个代码中,孩子和家长应该互相提供时间信息,接收者应该打印出来。当我在家长进程上找到时间并尝试在家长进程上打印时,它工作正常。但当我尝试通过管道发送时,它会写一行奇怪的问号和z字母。我对最后一行进行了注释,以防有人试图执行代码。抱歉,代码太乱了,但我无法在当前键盘上修复它

  #include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<signal.h>
#include<stdint.h>
#include<string.h>
#include<time.h>


void formatted_time(char* sender_name, char* receiver_name, char output[]);
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* child2="Child2";
    char result[80];
    char buffer[80];
    int firstchild,secondchild,read1,read2,read3;
    firstchild=fork();
        int mypipe[2];
    int mypipe2[2];
    int mypipe3[2];

        if(pipe(mypipe) == -1) {
          perror("Pipe failed");
          exit(1);
        }

        if(firstchild == 0)            //first child
        {
         close(mypipe[1]);    //Closing  the output  of pipe
    sleep(3);
    read1=read(mypipe[0],buffer,sizeof(buffer));    
     printf("%s\n",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);   
    write(mypipe[1],result,strlen(result)+1);
    //printf("%s\n",result);
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效格式的时间(字符*发送方名称,字符*接收方名称,字符输出[]);
无效格式化的\u时间(字符*发送方\u名称,字符*接收方\u名称,字符输出[])
{
结构时间值电视;
时间不是现在;
struct tm*nowtm;
char-tmbuf[80];
gettimeofday(&tv,NULL);
nowtime=tv.tv_秒;
nowtm=本地时间(&nowtime);
strftime(tmbuf,80,“%Y-%m-%d%H:%m:%S”,
nowtm);
sprintf(输出,“%s:在%s的时间是%s.”,接收方名称,发送方名称,tmbuf);
}
int main(int argc,字符**argv)
{
char*parent=“parent”;
char*child1=“child1”;
char*child2=“child2”;
字符结果[80];
字符缓冲区[80];
int firstchild,secondchild,read1,read2,read3;
firstchild=fork();
int mypipe[2];
int mypipe2[2];
int mypipe3[2];
如果(管道(mypipe)=-1){
perror(“管道故障”);
出口(1);
}
if(firstchild==0)//第一个子
{
close(mypipe[1]);//关闭管道的输出
睡眠(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf(“%s\n”,缓冲区);
}否则{
secondchild=fork();//创建第二个子对象
if(secondchild==0)//第二个子
{
睡眠(6);
}else{//Parent
关闭(mypipe[0]);//关闭管道的输入
格式化时间(父项、子项1、结果);
写入(mypipe[1],result,strlen(result)+1);
//printf(“%s\n”,结果);

您的问题是在创建管道之前执行了一个
fork
调用。因此,实际上您
read
不读取任何内容,而您的
printf
打印分配了
缓冲区的堆栈上的垃圾

这是您的代码修复。我还在父级中添加了一个
wait
调用,以避免子级不知从何处打印到控制台:)

#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效格式化的\u时间(字符*发送方\u名称,字符*接收方\u名称,字符输出[]){
结构时间值电视;
时间不是现在;
struct tm*nowtm;
char-tmbuf[80];
gettimeofday(&tv,NULL);
nowtime=tv.tv_秒;
nowtm=本地时间(&nowtime);
strftime(tmbuf,80,“%Y-%m-%d%H:%m:%S”,nowtm);
sprintf(输出,“%s:在%s的时间是%s.”,接收方名称,发送方名称,tmbuf);
}
int main(int argc,字符**argv){
char*parent=“parent”;
char*child1=“child1”;
字符结果[80];
字符缓冲区[80];
int firstchild,secondchild,read1;
int mypipe[2];
如果(管道(mypipe)=-1){
perror(“管道故障”);
出口(1);
}
firstchild=fork();
如果(firstchild==0){//first child
close(mypipe[1]);//关闭管道的输出
睡眠(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf(“%d%s\n”,read1,缓冲区);
}否则{
secondchild=fork();//创建第二个子对象
如果(secondchild==0){//secondchild
睡眠(6);
}else{//Parent
关闭(mypipe[0]);//关闭管道的输入
格式化时间(父项、子项1、结果);
int w;
w=写入(mypipe[1],结果,strlen(结果)+1);
printf(“%d字节写入\n”,w);
等待(空);
}
}
返回0;
}

在创建管道之前,您正在分叉第一个子管道。因此,您创建了两个不同的管道:一个在父管道中,另一个在子管道中。之后,如果您从第一个子管道中创建的管道中读取,则读取的
返回0,表示未读取任何数据。因此,缓冲区中的数据无效,并且
printf。请始终检查API调用的返回代码

用户“nsilent22”已经对您的代码进行了很好的清理。在末尾添加3个关闭括号
}
以关闭所有块后,您至少在创建管道后移动了分叉:

firstchild=fork();
if (firstchild == 0) { // first child
在read调用中,您应该检查返回代码:

  read1=read(mypipe[0],buffer,sizeof(buffer));
  if (read1 <= 0) {
    printf("read failed with code %d\n, ", read1);
  } else {
    printf("%s\n",buffer);
  }
read1=read(mypipe[0],buffer,sizeof(buffer));

if(read1)你从管道中
从哪里读取
?我在代码中的任何地方都看不到它。另外,使用
睡眠
是一种非常粗糙的尝试和同步进程的方法,在某个点上肯定会中断。我认为这会写入管道的另一端。write(mypipe[1],result,strlen(result)+1)我可能错了,但这是我在书中学到的。是的,那是
调用,但是
在哪里?哇,我忘了添加它了。但它仍然只写了一个问号。你的代码似乎不完整。这很有效。在我的代码中,我可以在第二个孩子和父母之间传输数据,这与你所做的相符正在说。读入第一个孩子不工作,但读入第二个孩子工作。我还有一个小问题。我如何使用另一个管道将信息从孩子一传递到孩子二。以及从孩子二传递到家长(像一个循环)。我尝试创建两个不同的管道,并让它们等待3秒才能获得时间。但最终所有的时间值都是相同的。@JonathanPark:创建两个额外的管道(一个用于child1->child2,另一个用于child2->parent)应该可以。你应该在父进程中创建它们。例如,我将在我的帖子中更新代码并添加另一个管道,但它不会打印任何内容。从child1发送到child2的代码:(没有错误检查)。是的,它可以工作。和我以前的方式一样
  read1=read(mypipe[0],buffer,sizeof(buffer));
  if (read1 <= 0) {
    printf("read failed with code %d\n, ", read1);
  } else {
    printf("%s\n",buffer);
  }