2010-04-21 4 views
12

Мне нужен мой родительский и дочерний процесс, чтобы оба могли читать и писать одну и ту же переменную (типа int), поэтому она является «глобальной» между этими двумя процессами.C - fork() и общая память

Я предполагаю, что это будет использовать какую-то взаимосвязь между процессами и иметь одну переменную в одном обновляемом процессе.

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

Какой метод лучше всего, и вы могли бы предоставить ссылку на учебник noobs для него.

Спасибо.

ответ

15

Поскольку вы упоминаете, используя вилку(), я предполагаю, что вы живете на * NIX-системы

От Unix.com

Основной способ обмена данными между процессами, использующими UNIX IPCs являются :

(1) Общая память;

(2) Разъемы:

Есть другие UNIX IPCs включая

(3) очереди сообщений.

(4) Семафоры;

(5) Сигналы.

Ваш лучший выбор (для IPC) - использовать сегменты разделяемой памяти на основе вашего сообщения . Возможно, вам понадобится использовать семафоры , чтобы гарантировать, что операции общей памяти являются атомарными.

учебника по разветвлению и разделяемая память на Dev сараю:

http://forums.devshed.com/c-programming-42/posix-semaphore-example-using-fork-and-shared-memory-330419.html

другое описание более глубокое использование многопоточности (если appilcable для вашего приложения) можно найти здесь:

https://computing.llnl.gov/tutorials/pthreads/

+0

Пошел с общей памятью в конце. – Cheetah

+2

Подозрительно похожий текст здесь (вы можете указать ссылку для кредита?): Http://www.unix.com/programming/857-fork-ipc.html – sje397

+0

@ sje397: Спасибо, что указали, что неудача цитаты – sum1stolemyname

4

Если вам нужно обмениваться памятью, возможно, использование потоков вместо процессов было бы лучшим решением?

+0

Сво назначение для университета. Вы должны использовать fork() специально – Cheetah

2

Вариант, который я использовал недавно в общей памяти, заключается в том, чтобы открыть mmap перед разветвлением. Это позволяет избежать определенных ограничений общей памяти api. У вас нет ограничения по размеру (диапазон адресов ограничен), вам не нужно генерировать ключ из этого абсолютного файла. Вот пример того, как я сделал это (я ушел из проверки для краткости ошибки)

ppid = getpid(); 
shm_size = ...; 

char *tmpFile = tempnam(NULL, "SHM_"); /* Generate a temp file which is virtual */ 

/* Before we fork, build the communication memory maps */ 
mm = open(tmpFile, O_RDWR|O_CREAT|O_TRUNC, 0664)); /* Create the temp file */ 
ftruncate(mm, shm_size);        /* Size the file to the needed size, on modern Unices it's */ 
                 /* a sparse file which doesn't allocate anything in the file system */ 

/* The exact type of comm_area left to the implementer */ 
comm_area *pCom = (comm_area *)mmap(NULL, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, mm, 0); 
if(pCom == (comm_area*)MAP_FAILED) handle_error(); 
close(mm);        /* We can close the file, we won't access it via handle */ 
unlink(tmpFile);       /* We can also remove the file so even if we crash we won't let corpses lying */ 
free(tmpFile); 

/* Initialise some shared mutexes and semaphores */ 
pthread_mutexattr_t mattr; 
pthread_mutexattr_init(&mattr); 
pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); 
pthread_mutex_init(&pCom->stderr_mutex, &mattr);   

/* nSonAsked, global variable with the number of forked processes asked */ 
for(nSon=0; nSon<nSonsAsked; nSon++) { 

    printf("Setup son #%.2u ",nSon+1); 
    /* Initialize a semaphore for each child process */ 
    sem_init(&pCom->sem_ch[nSon], USYNC_PROCESS, 0); 
    if(fork() == 0 { 
    ... /* do child stuff*/ 
    return; 
    } 
    /* Father, cleans up */ 
    pthread_mutexattr_destroy(&mattr); 
    ... 
    return;