簡體   English   中英

在C中讀取和寫入管道結構

[英]Reading and writing a structure to a pipe in C

我正在嘗試編寫一種結構,該結構由字符數組,整數值和指向管道的指針組成。 該結構表示單鏈列表中的節點。

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

該程序的目標是使用管道將節點從多個並發子進程傳遞到父進程。 我實現的管道結構似乎可以與常規字符數組一起正常工作,但是如果我嘗試傳遞整個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語句返回空的復現時間。

知道我在做什么錯嗎?

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

您在哪里為NODE結構分配存儲空間? freqCheck是否分配存儲空間? 在父進程中,當您調用read()然后調用printf ,您傳入的是未初始化的NODE指針,因此,您當然會得到未定義的行為。

您需要考慮兩件事:
1)執行協調:

這就是諸如鎖,信號燈,事件等之類的東西。 它們按照指令(您的代碼行)的運行順序執行命令。 正是由於這個原因,這些版本中有一些版本在進程之間運行,就像為線程運行的版本一樣。 您在這里需要一個信號燈-節點完全傳輸后,編寫器進程應將sem發布(),而讀取器進程應在嘗試讀取下一個之前在sem上等待()。

2)記憶體:
進程不共享地址空間。 因此,讀取器和寫入器進程具有的堆是不同的內存塊。 管道可以正常工作,但它像套接字一樣,具有將對象序列化和反序列化為原始字節流的所有麻煩。 考慮到您的結構有多小,您可能要考慮的另一件事是共享內存。

最后要考慮的一件事:您需要在子進程中更新指向節點結構中“下一個”節點的指針。 同樣,它將把這些節點復制到其自己的地址空間中的位置,因此必須相應地更新“下一個”指針。

使用緩沖的讀取者讀取數據,直到讀取整個結構為止,因為可以從父級執行代碼,然后再從子級執行代碼,然后讀取不存在的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM