在 C 中读取结构体并将其写入管道

发布于 10-14 09:32 字数 3848 浏览 7 评论 0原文

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

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


            }

当父进程尝试从管道读取并解释结构的属性之一时,我只会返回空值。

我使用 2 元素整数数组的数组来跟踪每个子进程的管道。上面的 printf 语句返回 null 恢复时间。

知道我做错了什么吗?

FrqCheck 方法的代码:

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

I'm attempting to write a structure consisting of a an array of characters, an integer value, and a pointer to a pipe. The structure represents a node in a singly linked list.

//Define a linked-list node object
typedef struct node{
    char word[128];
    int frequency;
    struct node *next;
} NODE;

The object of the program is to use a pipe to pass a node from several concurrent child processes to the parent. The pipe structure I've implemented seems to work fine with regular character arrays but won't work if I try to pass the entire node object.

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


            }

When the parent process attempts to read from the pipe and interpret one of the attributes of the structure, I just get null values back.

I'm using an array of 2 element integer arrays to keep track of each child processes' pipe. The printf statement above returns null revery time.

Any idea what I'm doing wrong?

Code for the FrqCheck method:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫七2024-10-21 09:32:51

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

Where are you allocating storage for your NODE structures? Does freqCheck allocate storage? In the parent process, when you call read() and then printf, you pass in an uninitialized NODE pointer, so of course you're getting undefined behavior.

绅士风度i2024-10-21 09:32:51

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

Use buffered read who reads data until whole structure will be readed, because code from parrent can be executed before code from child then you reading data who not exists.

请持续率性2024-10-21 09:32:51

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

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

2)内存:
进程不共享地址空间。因此,读取器和写入器进程拥有的堆是不同的内存块。管道工作正常,但它就像一个套接字——将对象序列化和反序列化为原始字节流的所有麻烦。考虑到您的结构有多小,您可以考虑的另一件事是共享内存。

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

You need to consider 2 things:
1) Execution Coordination:

This is what things like locks, semaphores, events, etc. are for. They enforce an order on the order in which instructions (your lines of code) run. There are versions of these that operate between processes, just like the ones that operate for threads, for precisely this reason. You want a semaphore here- the writer process should post() the sem when a node has been fully transmitted, and the reader process should wait() on the sem before trying to read the next one.

2) Memory:
Processes do NOT share address space. Thus the heaps the reader and writer process have are different chunks of ram. A pipe works fine, but its like a socket- you have all the nastiness of serializing and de-serializing objects into raw streams of bytes. Another thing you could consider, given how small your structs are, is shared memory.

One last thing to consider: Your pointers to the "next" node in your node structure will need to be updated in the child process. Again, it is going to copy these nodes to locations in its own address space, so the 'next' pointers have to be updated accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文