I'm getting back into C from .NET so please forgive my code, but I'm trying to implement the atomic builtin incrementer across an existing multi process program.
I wrote up a test program, and I can't get it to work. It increments to 5 correctly, but each child increments the value to 6, rather than collectively incrementing it to 10. Monitor displays 5.
I've tried various changes using a global int versus passing the static int from main to the child, but same result. Any help is appreciated, thank you.
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 }
If memory serves me correctly, when you
fork()
your process, the child process gets a copy of the variables, or rather, the variables are copy-on-write. That is, you essentially refer to the same data until you try and change it. What you are trying to accomplish requires more than just astatic
variable declared at the top of your code. You need to look at using shared memory so that you can share the variable(s) across process spaces. Since that is something that would take a long time to get into and really is not a 5-line answer, I will have to come back and edit this later with more detail. However, if you look up theshm_get
function in your man pages (along with the various othershm_*
functions that go along with it), the documentation is quite extensive. There are also a number of tutorials out there on the web: search for "POSIX IPC shared memory tutorial example" and you should get a variety of hits describing how to do it.