1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pthread.h>
4
5 #include "common.h"
6 #include "common_threads.h"
7
8 int max;
9 volatile int counter = 0; // shared global variable
10
11 void *mythread(void *arg) {
12 char *letter = arg;
13 int i; // stack (private per thread)
14 printf("%s: begin [addr of i: %p]\n", letter, &i);
15 for (i = 0; i < max; i++) {
16 counter = counter + 1; // shared: only one
17 }
18 printf("%s: done\n", letter);
19 return NULL;
20 }
21
22 int main(int argc, char *argv[]) {
23 if (argc != 2) {
24 fprintf(stderr, "usage: main-first <loopcount>\n");
25 exit(1);
26 }
27 max = atoi(argv[1]);
28
29 pthread_t p1, p2;
30 printf("main: begin [counter = %d] [%p]\n", counter,
31 &counter);
32 Pthread_create(&p1, NULL, mythread, "A");
33 Pthread_create(&p2, NULL, mythread, "B");
34 // join waits for the threads to finish
35 Pthread_join(p1, NULL);
36 Pthread_join(p2, NULL);
37 printf("main: done\n [counter: %d]\n [should: %d]\n",
38 counter, max*2);
39 return 0;
40 }
Figure 26.6: Sharing Data: Uh Oh (t1.c) (updated)
|
|
$ ./t1 1000
main: begin [counter = 0] [0x5595c870602c]
A: begin [addr of i: 0x7f1d4b103edc]
A: done
B: begin [addr of i: 0x7f1d4a902edc]
B: done
main: done
[counter: 2000]
[should: 2000]
$ ./t1 10000
main: begin [counter = 0] [0x5614fcebb02c]
A: begin [addr of i: 0x7f2d6429eedc]
B: begin [addr of i: 0x7f2d63a9dedc]
A: done
B: done
main: done
[counter: 16198]
[should: 20000]
$ ./t1 10000
main: begin [counter = 0] [0x55e639cc602c]
A: begin [addr of i: 0x7fe89de71edc]
B: begin [addr of i: 0x7fe89d670edc]
A: done
B: done
main: done
[counter: 13548]
[should: 20000]
$ ./t1 10000
main: begin [counter = 0] [0x55bc1502402c]
A: begin [addr of i: 0x7f12e8365edc]
A: done
B: begin [addr of i: 0x7f12e7b64edc]
B: done
main: done
[counter: 20000]
[should: 20000]
$ ./t1 100000
main: begin [counter = 0] [0x563ec42ec02c]
A: begin [addr of i: 0x7ff3d02b7edc]
B: begin [addr of i: 0x7ff3cfab6edc]
A: done
B: done
main: done
[counter: 102446]
[should: 200000]
|