C - fork() и память обмена
Мне нужен мой родительский и дочерний процесс, чтобы оба могли читать и писать одну и ту же переменную (типа int), поэтому она является "глобальной" между двумя процессами.
Я предполагаю, что это будет использовать какую-то межпроцессную связь и иметь одну переменную в одном обновляемом процессе.
Я сделал быстрый google и IPC, и появились различные методы, но я не знаю, какая из них наиболее подходит для моей ситуации.
Итак, какой метод лучше всего, и вы могли бы предоставить ссылку на учебник noobs для него.
Спасибо.
Ответы
Ответ 1
Поскольку вы упоминаете использование fork(), я предполагаю, что вы живете в * nix-System
От Unix.com
Основной способ обмена данными между процессы с использованием IPC UNIX:
(1) Общая память;
(2) Сокеты:
Существуют и другие IPC UNIX, включая
(3) Очереди сообщений.
(4) Семафоры;
(5) Сигналы.
Лучше всего (для МПК) использовать сегментов разделяемой памяти на основе ваших после. Возможно, вам придется использовать семафоры для обеспечения того, чтобы общая память операции являются атомарными.
Учебник по forking и разделяемой памяти находится на dev shed:
http://forums.devshed.com/c-programming-42/posix-semaphore-example-using-fork-and-shared-memory-330419.html
можно найти еще одно подробное описание использования многопоточности (если оно доступно для вашего приложения):
https://computing.llnl.gov/tutorials/pthreads/
Ответ 2
Если вам нужно обмениваться памятью, возможно, использование потоков вместо процессов будет лучшим решением?
Ответ 3
Вариант, который я использовал недавно в общей памяти, - это открыть 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 */
/* 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;