我从.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 }
答案 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?你真的必须查阅
的文档fork
之后如何共享(或不共享)内存。