sync example note1
coconutnut

Cync example for C concurrent programing

Threads

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <assert.h>

#define RUNS (4096 * 256)
#define THREADS 4

static int counter = 0;

void *count(void* null) {
printf("New thread created\n");

// do something
}

int main() {
// declare an array of 4 threads
pthread_t handlers[THREADS];

for (intptr_t i = 0; i < THREADS; i++) {
int res = pthread_create(&handlers[i], NULL, count, NULL);
assert(!res);
}

for (int i = 0; i < THREADS; i++) {
int res = pthread_join(handlers[i], NULL);
assert(!res);
}

if (counter != RUNS * THREADS) {
printf("Didn't count so well. :/, found %d\n", counter);
} else {
printf("Counted up to %d.\n", counter);
}
}

Lock

1
2
3
4
5
6
7
8
9
10
11
#include "lock.h"

void* count(void* null) {
for (int r = 0; r < RUNS; r++) {
lock_acquire(&lock);
counter++;
lock_release(&lock);
}

return NULL;
}

Better version: use lock_wait(&lock) and lock_wake_up(&lock) to prevent bucy wait, but rely on a notification.

Atomic variable

Atomic variables (~atomic registers) do not enforce atomic operation blocks.

Need to use atomic operation.

1
2
3
4
5
6
7
8
9
static atomic_int counter = 0;

void* count(void* null) {
for (int r = 0; r < RUNS; r++) {
atomic_fetch_add(&counter, 1);
}

return NULL;
}

Another example

1
2
3
4
int expected = 0;
if (atomic_compare_exchange_strong(&leader[r], &expected, tid)) {
atomic_fetch_add(&nb_leaders[r], 1); // used to check correctness
}

Debug

当有include .h时,报错

1
clang: error: linker command failed with exit code 1

可以在Terminal

1
2
gcc election2.c lock.c -o ekection2.o
./election2.o