fork (), общая память и указатели в C - PullRequest
0 голосов
/ 31 октября 2019

Я не могу поделиться указателем на объект среди процессов с общей памятью.

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

    // Data to be shared among processes
    struct Shared_data {
        int setPointCounter;
        struct Point old_point;
        pthread_mutex_t my_mutex;
    } *shd;

Структура объявленакак глобальный (он расположен перед main (), скажем так).

Я инициализирую общую память в основную:

shd = (struct Shared_data *) (mmap(NULL, sizeof *shd, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0));

, а затем в определенный момент я делаю форк(). Это работает нормально.

Проблема возникает, когда я должен поделиться чем-то вроде этого:

    // Data to be shared among processes
    struct Shared_data {
        int setPointCounter;
        struct Point old_point;
        MyObject *obj;
        pthread_mutex_t my_mutex;
    } *shd;

В основном я вызываю функцию из сторонней библиотеки, которая возвращает указатель наобъект типа MyObject, и я хотел бы поделиться им в некотором роде. Как я могу это сделать?

При поиске в Интернете я нашел что-то, связанное с относительными указателями, но я не уверен, что это сработает, и в то же время я не знаю, как это сделать. это правильный путь.

Я работаю в Linux (Slackware 64 14.2), и язык C / C ++ (в основном это C, на самом деле).

Заранее спасибо за ваше время.

1 Ответ

0 голосов
/ 05 ноября 2019

По сути, указатель - это адрес некоторых данных в виртуальном пространстве одного процесса. Вы не можете совместно использовать указатели между процессами, потому что эти указатели будут интерпретироваться в другом адресном пространстве (в общем, это также относится к виртуальному пространству режима ядра и режиму пользователя того же самого процесса ). Давайте рассмотрим пример ... у вас есть некоторые распределения (между ними вы сделали mmap(2) распределение), а затем вы fork(2) другой процесс. До этого все адреса памяти указывали на одни и те же места, если учесть, что оба процесса существовали до разветвления, они делали бы одно и то же, получали одинаковые результаты и т. Д.

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

Теперь давайте предположим, что у вас есть указатель в одном процессе, который указывает на структуру данных, которую вы хотите поделиться с другим. Но другой процесс даже не выделил то же самое ... поэтому передача, например, 0x00456211ff другому процессу, укажет на место в другом процессе, где ничего не было выделено (что приводит к сигналу SIGSEGV и прерыванию процесса).

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

...