原子内置函数可以跨多个进程使用吗?

时间:2011-02-24 21:35:05

标签: c fork atomic built-in-types

我从.NET回到C,所以请原谅我的代码,但我正在尝试在现有的多进程程序中实现原子内置增量器。

我写了一个测试程序,我无法让它工作。它正确递增到5,但是每个子项将值递增到6,而不是将它集中递增到10.监视器显示5.

我尝试使用全局int进行各种更改,而不是将static int从main传递给子进程,但结果相同。感谢任何帮助,谢谢。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <sys/types.h>
  4 #include <stdlib.h>
  5 #include <unistd.h>
  6 #include "list.h"
  7 
  8 #define N 5
  9 static int globalcount = 0;
 10 
 11 void Monitor()
 12 {
 13     sleep(1);
 14     printf("Monitor Value %d\n", globalcount);
 15 }
 16 
 17 void Child()
 18 {   
 19     int value = __sync_add_and_fetch(&globalcount, 1);
 20     printf("Child Value %d\n", value);
 21 }
 22 
 23 int main(int argc, char** argv)
 24 {
 25     int i;
 26     int value;
 27     static int count = 0;
 28     pid_t pid[N];
 29     pid_t pidkey;
 30 
 31     for (i = 0; i < N; ++i) {
 32         value = __sync_add_and_fetch(&globalcount, 1);
 33         printf("Value %d\n", value);
 34     }
 35     printf("\n\n\n");
 36 
 37     if ((pidkey = fork()) == 0) {
 38         Monitor();
 39     } else if (pidkey > 0) {
 40         for (i = 0; i < N; i++)
 41         {
 42             if ((pid[i] = fork()) == 0) {
 43                 Child();
 44                 break;
 45             }
 46         }
 47     }
 48     return 0;
 49 }   

3 个答案:

答案 0 :(得分:4)

如果内存正确地为我服务,当您fork()进程时,子进程会获得变量的副本,或者更确切地说,变量是写时复制的。也就是说,在尝试更改之前,您基本上会引用相同的数据。您要完成的任务不仅仅需要在代码顶部声明的static变量。您需要查看使用共享内存,以便可以跨进程空间共享变量。由于这需要花费很长时间才能进入并且实际上不是5行答案,因此我将不得不回过头来更详细地编辑它。但是,如果您在手册页中查找shm_get函数(以及随之而来的各种其他shm_*函数),则文档非常广泛。网上还有一些教程:搜索“POSIX IPC共享内存教程示例”,你应该得到各种描述如何做的命中。

答案 1 :(得分:2)

作为Will says,由fork()创建的子进程独立于其父进程(以及彼此)。它们在概念上都以正常方式分配了自己的私有数据副本。

如果您希望在进程之间共享内存,则必须在致电fork()之前明确创建共享内存区域:

int *globalcount = mmap(0, sizeof *globalcount, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*globalcount = 0;

答案 2 :(得分:0)

这些原子操作不是C标准的一部分,但是,它们计划成为下一个标准的一部分。

你似乎使用的那些看起来好像你正在使用gcc?你真的必须查阅

的文档
  • 你的编译器用于原子原语,以及它们如何表现w.r.t线程共享内存(相同的地址空间)和进程共享内存(不同的虚拟地址指向相同的“物理”内存)。
  • 你的操作系统(unix?)知道在fork之后如何共享(或不共享)内存。