【发布时间】:2011-02-10 13:36:04
【问题描述】:
我需要我的父进程和子进程都能够读取和写入相同的变量(int 类型),因此它在两个进程之间是“全局的”。
我假设这将使用某种跨进程通信,并在一个进程上更新一个变量。
我做了一个快速的 google 和 IPC,各种技术出现了,但我不知道哪种技术最适合我的情况。
那么什么技术最好,你能提供一个新手教程的链接吗?
谢谢。
【问题讨论】:
标签: c ipc fork shared-memory
我需要我的父进程和子进程都能够读取和写入相同的变量(int 类型),因此它在两个进程之间是“全局的”。
我假设这将使用某种跨进程通信,并在一个进程上更新一个变量。
我做了一个快速的 google 和 IPC,各种技术出现了,但我不知道哪种技术最适合我的情况。
那么什么技术最好,你能提供一个新手教程的链接吗?
谢谢。
【问题讨论】:
标签: c ipc fork shared-memory
由于您提到使用 fork(),我假设您生活在 *nix 系统上
来自Unix.com
之间共享数据的主要方式 使用 UNIX IPC 的进程是:
(1) 共享内存;
(2) 套接字:
还有其他 UNIX IPC,包括
(3) 消息队列。
(4) 信号量;
(5) 信号。
您最好的选择(对于 IPC)是使用 共享内存段,基于您的 邮政。您可能需要使用信号量 以确保共享内存 操作是原子的。
关于分叉和共享内存的教程在 dev shed 上:
可以在此处找到有关使用多线程的另一个更深入的描述(如果适用于您的应用程序):
【讨论】:
如果您需要共享内存,也许使用线程而不是进程会是更好的解决方案?
【讨论】:
我最近使用的共享内存的一个变体是在分叉之前打开一个 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;
【讨论】: