Mmap и структура - PullRequest
       13

Mmap и структура

2 голосов
/ 19 мая 2010

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

typedef struct container {
    sem_t resource, mutex;
    int counter;
} container;

и использовать таким образом (в основном приложении и то же самое в подчиненных процессах)

container *memory;

shm_unlink("MYSHM"); //just in case
fd = shm_open("MYSHM", O_RDWR|O_CREAT|O_EXCL, 0);

if(fd == -1) {
    printf("Error");
    exit(EXIT_FAILURE);
}
memory = mmap(NULL, sizeof(container), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ftruncate(fd, sizeof(container));

Все нормально, когда я использую одну из функций sem_, но когда я пытаюсь сделать что-то вроде

memory->counter = 5;

Это не работает. Возможно, у меня что-то не так с указателями, но я попробовал почти все, и ничего не работает. Может быть, есть лучший способ для разделения переменных, структур и т. Д. Между процессами? К сожалению, мне не разрешено использовать boost или что-то похожее, код предназначен для образовательных целей, и я намерен сделать его максимально простым.

Ответы [ 2 ]

6 голосов
/ 19 мая 2010

Поскольку вы используете shm_unlink() непосредственно перед shm_open(), ваши два процесса никогда не открывают один и тот же объект общей памяти - каждый из них создает новый отдельный объект (даже если они имеют одно и то же имя).


Непонятно, что вы подразумеваете под "не работает". Следующий минимальный пример, основанный на вашем коде, прекрасно работает для меня. Что это делает для вас?

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>

typedef struct container {
    sem_t resource, mutex;
    int counter;
} container;

int main()
{
    container *memory;
    int fd = shm_open("MYSHM", O_RDWR|O_CREAT|O_EXCL, 0);

    if(fd == -1) {
        perror("shm_open");
        return 1;
    }

    ftruncate(fd, sizeof(container));
    memory = mmap(NULL, sizeof(container), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

    memory->counter = 5;
    printf("%d\n", memory->counter);

    return 0;
}

При просмотре кода происходит сбой, поскольку вы пытаетесь получить доступ к дескриптору файла в дочернем процессе после exec(), а shm_open по умолчанию устанавливает флаг FD_CLOEXEC, поэтому дескриптор файла больше не открыт в ребенок. Так что вам просто нужно сбросить этот флаг в основном процессе (например, сразу после проверки на ошибку после shm_open):

fdflags = fcntl(fd, F_GETFD);
fdflags &= ~FD_CLOEXEC;
fcntl(fd, F_SETFD, fdflags);
0 голосов
/ 19 мая 2010

Почему вы вообще звоните shm_open? Очень хороший способ сделать это - просто вызвать open для какого-то пути и использовать его.

...