fork()没有做我想要的

时间:2016-10-17 16:51:51

标签: c unix concurrency synchronization fork

所以,我的程序应该这样做:我在父进程中向文件“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”然后我可以从父进行获取然后“String sent “它看起来像这样:

String

Child finished
input
String sent

有人可以帮帮忙吗?

2 个答案:

答案 0 :(得分:1)

在儿童分会

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

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

(那甚至没有提到父母发送的字符串没有零终止符,而且孩子从来都不会将其收到的终止归零。)

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

答案 1 :(得分:0)

您的读入子进程未被阻止。

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

你必须使用从父母到孩子的管道。

从父端写入管道。

从孩子的管道中读取。 这会阻止子进程,直到阅读完成。

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

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