This shows you the differences between two versions of the page.
— |
os_cp:find_out_what_is_going_on2 [2024/04/17 23:33] (current) jkonczak utworzono |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== Yet another reason that makes concurrent programming harder. ===== | ||
+ | |||
+ | Below, there is a piece of code that can be compiled by issuing: | ||
+ | <code bash>gcc -g -O0 sb.c -o sb</code> | ||
+ | |||
+ | __Analyze the code and tell which results can be output.__ | ||
+ | \\ | ||
+ | Remember that global variables are by default zero-initialized. | ||
+ | |||
+ | Run the program multiple times with the following command, and observe the results: | ||
+ | <code bash>( for((i=0;i<10000;++i)); do ./sb; done ) | sort | uniq -c</code> | ||
+ | |||
+ | Finally, explain the results. | ||
+ | |||
+ | <html><div style="line-height:1em"></html> | ||
+ | <code c sb.c> | ||
+ | #include <pthread.h> | ||
+ | #include <stdatomic.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | volatile char data[64 * 3]; | ||
+ | volatile char *const a = data + 64; | ||
+ | volatile char *const b = data + 64 * 2; | ||
+ | atomic_char vA, vB, control; | ||
+ | |||
+ | void *th1(void *arg) { | ||
+ | control++; | ||
+ | while (control != 2); | ||
+ | |||
+ | *b = 1; | ||
+ | vA = *a; | ||
+ | |||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | void *th2(void *arg) { | ||
+ | control++; | ||
+ | while (control != 2); | ||
+ | |||
+ | volatile int dummy = 44; | ||
+ | while (dummy--); | ||
+ | |||
+ | *a = 1; | ||
+ | vB = *b; | ||
+ | |||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | pthread_t t1, t2; | ||
+ | pthread_create(&t1, NULL, th1, NULL); | ||
+ | pthread_create(&t2, NULL, th2, NULL); | ||
+ | pthread_join(t1, NULL); | ||
+ | pthread_join(t2, NULL); | ||
+ | printf("%d %d\n", vA, vB); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | <html></div></html> | ||
+ | |||
+ | |||
+ | ~~META: | ||
+ | language = en | ||
+ | ~~ | ||