Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.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语言中读写管道结构_C_Struct_Fork_Pipe - Fatal编程技术网

在C语言中读写管道结构

在C语言中读写管道结构,c,struct,fork,pipe,C,Struct,Fork,Pipe,我试图编写一个由字符数组、整数值和指向管道的指针组成的结构。该结构表示单链表中的节点 //Define a linked-list node object typedef struct node{ char word[128]; int frequency; struct node *next; } NODE; 程序的目标是使用管道将节点从多个并发子进程传递到父进程。我实现的管道结构似乎可以很好地处理常规字符数组,但如果我试图传递整个节点对象,它将无法工作 //

我试图编写一个由字符数组、整数值和指向管道的指针组成的结构。该结构表示单链表中的节点

//Define a linked-list node object
typedef struct node{
    char word[128];
    int frequency;
    struct node *next;
} NODE;
程序的目标是使用管道将节点从多个并发子进程传递到父进程。我实现的管道结构似乎可以很好地处理常规字符数组,但如果我试图传递整个节点对象,它将无法工作

    //for each file argument, create a child process
        for (i = 1; i < argc; i ++)
        {
            pipe(p[i-1]);
            pid = fork();

            if (pid == 0)
            {
                //child process
                close(p[i-1][0]);
                NODE *tmp;
                NODE *out = freqCheck(argv[i], tmp);
                write(p[i-1][1], out, sizeof(NODE));
                exit(0);
            }
        }
if (pid > 0){
                //parent process
                int j;
                for (j = 0; j < argc-1; j++)
                {
                    close(p[j][1]);
                    NODE *tmp;
                    read(p[j][0], tmp, sizeof(NODE));

                    printf("%s\n", tmp->word);
                }


            }

您在哪里为
节点
结构分配存储?
freqCheck
是否分配存储?在父进程中,当您调用
read()
然后调用
printf
时,您会传入一个未初始化的
节点
指针,因此您当然会得到未定义的行为。

您在哪里为
节点
结构分配存储?
freqCheck
是否分配存储?在父进程中,当您调用
read()
然后调用
printf
时,您会传入一个未初始化的
节点
指针,因此您当然会得到未定义的行为。

使用缓冲读取,读取数据直到读取整个结构,因为来自代码的代码可以在子代码之前执行,然后读取不存在的数据。

< P>使用缓冲读数据,直到整个结构将被读取,因为来自PARROE的代码可以在孩子的代码之前执行,然后读取不存在的数据。

您需要考虑2件事:
1) 执行协调:

这就是锁、信号量、事件等的用途。它们根据指令(代码行)的运行顺序强制执行命令。正是出于这个原因,这些版本在进程之间运行,就像为线程运行的版本一样。这里需要一个信号量——当一个节点被完全传输时,writer进程应该在sem上post(),而reader进程应该在尝试读取下一个节点之前在sem上等待()

2) 内存:
进程不共享地址空间。因此,读写器进程的堆是不同的ram块。管道可以很好地工作,但它就像一个套接字——将对象序列化和反序列化为原始字节流的所有缺点都存在。考虑到结构的大小,可以考虑的另一件事是共享内存。


最后要考虑的一点是:指向节点结构中“下一个”节点的指针需要在子进程中更新。同样,它将把这些节点复制到自己地址空间中的位置,因此必须相应地更新“下一个”指针 1) 执行协调:

这就是锁、信号量、事件等的用途。它们根据指令(代码行)的运行顺序强制执行命令。正是出于这个原因,这些版本在进程之间运行,就像为线程运行的版本一样。这里需要一个信号量——当一个节点被完全传输时,writer进程应该在sem上post(),而reader进程应该在尝试读取下一个节点之前在sem上等待()

2) 内存:
进程不共享地址空间。因此,读写器进程的堆是不同的ram块。管道可以很好地工作,但它就像一个套接字——将对象序列化和反序列化为原始字节流的所有缺点都存在。考虑到结构的大小,可以考虑的另一件事是共享内存。


最后要考虑的一点是:指向节点结构中“下一个”节点的指针需要在子进程中更新。同样,它将把这些节点复制到自己地址空间中的位置,因此必须相应地更新“下一个”指针

是频率检查构造链表并为每个节点分配内存。该方法扫描文件中的单词,并确定出现最多的单词。它返回一个节点实例。@user362685,无论您使用
freqCheck
做什么,您在父进程中仍然有未定义的行为。您从未为
NODE*tmp
分配存储,但您将其传递给
read()
,然后将其传递给
printf
。这就解决了问题,谢谢。只需要将其更改为NODE*tmp=malloc(sizeof(NODE))。是的,频率检查构造链表并为每个节点分配内存。该方法扫描文件中的单词,并确定出现最多的单词。它返回一个节点实例。@user362685,无论您使用
freqCheck
做什么,您在父进程中仍然有未定义的行为。您从未为
NODE*tmp
分配存储,但您将其传递给
read()
,然后将其传递给
printf
。这就解决了问题,谢谢。只需要将其更改为NODE*tmp=malloc(sizeof(NODE))。我已尝试向父代码添加wait()调用,以确保在子代码完成后父代码将执行,但得到相同的结果。我已尝试向父代码添加wait()调用,确保父级将在子级完成后执行,但我得到相同的结果。
//Method for determining the most occuring word
NODE * freqCheck(char *file, NODE *max)
{
    int i; 
    FILE *f;
    char str[128];

    //Set up head and tail nodes
    NODE *head = NULL;
    NODE *tail = NULL;

    if ((f = fopen(file, "r")) == NULL)
        {
            //sprintf(output, "%s could not be opened.", file);
        }else
        {
            //scan each word of the input file
            while(fscanf(f, "%s ", str) != EOF)
            {
                //if the linked-list has no nodes, create one
                if (head == NULL)
                {
                    NODE *n;
                    n = (NODE *)malloc(sizeof(NODE));
                    strcpy(n->word, str);
                    n->frequency = 1;
                    n->next = NULL;
                    head = n;
                    tail = n;

                }else{  //search the linked list for the found word.

                    NODE *current = head;
                    int found = 0;

                    while((current != NULL) && (found == 0))
                    {
                        //if the word is found increment the frequency
                        if (strcmp(current->word, str) == 0)
                        {
                            current->frequency ++;
                            found = 1;
                        }else
                        {
                            current = current->next;
                        }
                    }

                    //if the word is not found, create a node and add to the liked-list
                    if (found == 0)
                    {
                        NODE *new;
                        new = (NODE *)malloc(sizeof(NODE));
                        strcpy(new->word, str);
                        new->frequency = 1;
                        new->next = NULL;
                        tail->next = new;
                        tail = new;
                    }
                }
            }
            //traverse the linked-list and find the word with the maximum frequency
            NODE *tmp = head;
            max = tmp;

            while (tmp != NULL)
            {
                if (tmp->frequency > max->frequency)
                {
                    max = tmp;
                }else
                {
                    tmp = tmp->next;
                }
            }
            //sprintf(output, "%s %s %d", file, max->word, max->frequency);
        }
    //printf("%s\n", max->word);
    return max;
}