【问题标题】:fork() doesn't do what I wantfork() 没有做我想做的事
【发布时间】:2016-10-17 16:51:50
【问题描述】:

所以,我的程序应该这样做:我在父进程中向文件“vaterkind”写入一条消息,然后用子进程读取它,将它写入一个字符串并放在屏幕上。我试过这段代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>

int main()
{
    FILE *vaterkind, *kindvater;

    char path1[]={"/home/user/Documents/vaterkind"}, path2[]={"/home/user/Documents/kindvater"}; //paths to files

    int ret, readyv=0, readyk=0;

    mkfifo(path1,0666); //makes fifos
    mkfifo(path2,0666);

    ret = fork();

    if(ret > 0) //parent
    {
        char data_in[50];
        char data_out[50];

        puts("String");
        gets(data_in);
        vaterkind = open(path1,O_WRONLY); //dad is able to write
        kindvater = open(path2,O_RDONLY); //child is able to read

        write(vaterkind,data_in,strlen(data_in)); //write input in vaterkind
        puts("String sent");

        readyv = 1;             // set ready

    }

    else if(ret == 0)           // child
    {
        char data[50],hex[50],ascii[50];
        int i = 0, j = 0;

        vaterkind = open(path1,O_RDONLY); //dad is able to read
        kindvater = open(path2,O_WRONLY); //child is able to write

        read(vaterkind,data,strlen(data)); //read input and write to data

        puts(data);

        puts("Child finished");
        return 0;

    }

    else
    {
        puts("Fork failed");
    }

    sleep(1);
    return 0;

}

但是当我启动程序时,我首先收到消息“字符串”,然后是一个符号(不知道为什么这里有一个符号),然后是“孩子完成”,然后我可以从父母那里获取,然后是“发送的字符串" 它看起来像这样:

String

Child finished
input
String sent

有人可以帮忙吗?

【问题讨论】:

  • 你在哪里关闭文件?
  • 您不需要孩子等到父母写入文件吗?此外,您的任何代码都没有错误检查,因此无法调试。 (如果 openreadwrite 失败怎么办?你甚至不会知道。)此外,你应该在父级和孩子。这在过去导致了大量的错误,这些错误已经损害了敏感信息。父母或孩子必须致电_exit 终止。
  • 我该如何让孩子等待?我尝试了一段时间,但它并没有真正起作用..

标签: c unix concurrency synchronization fork


【解决方案1】:

在子分支中

char data[50];
...
read(vaterkind,data,strlen(data))

此时data 包含垃圾,将strlen 应用于它根本没有意义。

(这甚至没有提到父母发送一个没有零终止符的字符串,而孩子从不费心零终止它收到的内容。)

您应该开发某种通信协议,以确保在任何时候孩子都知道应该从 FIFO 中读取多少字节。例如,父级可以先发送字符串的长度,然后再发送字符串的内容。孩子从阅读长度开始,然后从那里继续。

【讨论】:

    【解决方案2】:

    您在子进程中的读取未被阻止。

    所以它不会等到父进程完成。

    您必须使用从父级到子级的管道。

    从父端写入管道。

    从子管道中读取。 这会阻塞子进程,直到读取完成。

    以下是简单的设计,供您理解以及如何操作。

    int main(int argc, char *argv[])
    {
        //Two file descriptors for pipe read and write.
        int fd[2]; 
    
        // create a pipe with defined file descriptors
        pipe(fd);
    
        // fork() returns 0 for child process.
        //so below is a parent process.
        if (fork() != 0)
        {
            // close read-descriptor, you are only writing in parent.
            close(fd[0]);
    
            //write into the pipe
            write(fd[1], "your data to write", sizeof("your data"));
    
            // close the write descriptor
            close(fd[1]);
        }
        else
        {   
            // close the write-descriptor, you are only reading here
            close(fd[1]);
    
            // read here. this will block the process till your reading complete.
            read(fd[0], "your variable to read", sizeof("your variable"));
    
            // close the read-descriptor
            close(fd[0]);
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 2020-11-26
      • 2011-03-28
      • 1970-01-01
      • 2011-02-27
      相关资源
      最近更新 更多