Чтение и запись структуры в канал в C - PullRequest
0 голосов
/ 28 января 2011

Я пытаюсь написать структуру, состоящую из массива символов, целочисленного значения и указателя на канал.Структура представляет узел в односвязном списке.

//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 возвращает нулевое время восстановления.

Есть идеи, что я делаю неправильно?

Код для метода 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;
}

Ответы [ 3 ]

1 голос
/ 28 января 2011

Где вы выделяете хранилище для ваших NODE структур?freqCheck выделяет память?В родительском процессе, когда вы вызываете read(), а затем printf, вы передаете неинициализированный указатель NODE, поэтому, конечно, вы получаете неопределенное поведение.

0 голосов
/ 28 января 2015

Вам необходимо учесть 2 вещи:
1) Координация исполнения:

Это то, для чего нужны такие вещи, как блокировки, семафоры, события и т. Д. Они обеспечивают порядок в том порядке, в котором выполняются инструкции (ваши строки кода). Именно по этой причине существуют версии, которые работают между процессами, точно так же, как те, которые работают для потоков. Здесь вам нужен семафор - процесс записи должен опубликовать () sem, когда узел полностью передан, а процесс чтения должен подождать () в sem, прежде чем пытаться прочитать следующий.

2) Память:
Процессы НЕ разделяют адресное пространство. Таким образом, кучи, которые имеют читатель и писатель, представляют собой разные фрагменты памяти. Канал работает нормально, но он похож на сокет - у вас есть все возможности сериализации и десериализации объектов в виде сырых потоков байтов. Еще одна вещь, которую вы могли бы рассмотреть, учитывая, насколько маленькие ваши структуры, это общая память.

И еще одна последняя вещь: ваши указатели на «следующий» узел в структуре вашего узла должны быть обновлены в дочернем процессе. Опять же, он собирается скопировать эти узлы в местоположения в своем собственном адресном пространстве, поэтому «следующие» указатели должны быть соответственно обновлены.

0 голосов
/ 28 января 2011

Используйте буферизованное чтение, которое считывает данные до тех пор, пока не будет прочитана вся структура, потому что код от parrent может быть выполнен до того, как код от дочернего будет затем считываться с данными, которых не существует.

...