Массив структур в разделяемой памяти для двух процессов - PullRequest
0 голосов
/ 13 июня 2011

Я пытаюсь создать массив структур для совместного использования между родительским и дочерним процессами, используя "shmget". Я следую шаблону моего профессора, но он не включает структуры и массивы (в общей памяти хранится только целое число). Следующий код компилируется без предупреждений, но возвращает «0» в качестве вывода, я ожидаю увидеть «10». Что я делаю не так?

Также у меня возникают проблемы, когда я пытаюсь объявить новые переменные внутри дочерних процессов, я видел другие примеры, где это работает, но я не знаю, почему меня заставляют объявлять их перед форком каждый раз.

typedef struct { 
    char character;
    int number;
} item;

int main(int argc, char *argv[])
{
    int mem_id;

    mem_id = shmget(IPC_PRIVATE, 10*sizeof(item), SHM_R | SHM_W);
    item * x;
    item * y;
    item * list[10];

    switch(fork())
    {
        case -1:
            perror("Bad fork()"); exit(1);
        case 0:
            *list = shmat(mem_id, NULL, 0);
            if ((int *) list == (int *) -1)
            {perror("Child cannot attach"); exit(1);}           

            x->character = 'a';
            x->number = 10;

            list[0] = x;

            shmdt(list);
            exit(0);
        default:
            *list = shmat(mem_id, NULL, 0);
            if ((int *) list == (int *) -1)
            {perror("Child cannot attach"); exit(1);}

            wait((int *)0);
            y = list[0];
            shmdt(list);

            printf("%c %d\n", y->character, y->number);

            if (shmctl(mem_id, IPC_RMID, 0) <0)
                { perror("cannot remove shared memory"); exit(1);}

            return 0;
    }
    return 0;
}

1 Ответ

1 голос
/ 25 ноября 2011

Я удивлен, что вы не сделали segfault, поскольку:

  1. Вы не инициализируете x, как указывал Немо
  2. Ваш массив "list" на самом деле является массивом указателейПредметам вместо того, чтобы быть массивом Предметов.
  3. Самое главное.Вы разделяете разделяемую память перед тем, как распечатать значение в y.

Код должен выглядеть следующим образом:

typedef struct { 
    char character;
    int number;
} item;

int main(int argc, char *argv[])
{
    int mem_id;

    mem_id = shmget(IPC_PRIVATE, 10*sizeof(item), SHM_R | SHM_W);
    item *x;
    item *y;
    item *list;

    switch(fork())
    {
    case -1:
        perror("Bad fork()"); exit(1);
    case 0:
        list = (item *)shmat(mem_id, NULL, 0);
        if ((void *) -1 == (void *)list)
        {
            perror("Child cannot attach"); exit(1);
        }
        x = list;
        x->character = 'a';
        x->number = 10;

        shmdt(list); // No need for this
        exit(0);
    default:
        list = (item *)shmat(mem_id, NULL, 0);
        if ((void *) list == (void *) -1)
        {
           perror("Child cannot attach"); exit(1);
        }

        wait((int *)0);
        y = list;
        printf("%c %d\n", y->character, y->number);

        shmdt(list);

        if (shmctl(mem_id, IPC_RMID, 0) <0)
            { perror("cannot remove shared memory"); exit(1);}

        return 0;
    }
    return 0;
}
...