閒的蛋疼作了一個6.828的homeworkhtml
就是這裏 https://pdos.csail.mit.edu/6.828/2018/homework/barrier.htmldom
就是說須要咱們利用給的一個mutex,一個條件變量,實現一個barrier.this
感受barrier就是書上講的那種sleep lock。具體到這個例子,前面說的mutex和條件變量,也就是下面的mutex和cond,分別就是一個spinlock和一個sleeplock。spa
pthread_cond_wait(&cond, &mutex); // go to sleep on cond, releasing lock mutex pthread_cond_broadcast(&cond); // wake up every thread sleeping on cond
實際填充的內容在barrier{}裏面,實際上就是控制bstate.nthread的值,每個線程都檢測一下這個值,來知道本身是第一個仍是第二個進入線程的,若是是第一個的話就掛起來,是第二個的話就把第一個喚醒,這樣來保證兩個線程一塊兒進入每一個round。線程
我剛開始作的時候忘記每輪以後要round++了,困惑了很久。。。code
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <assert.h> #include <pthread.h> // #define SOL static int nthread = 1; static int round = 0; struct barrier { pthread_mutex_t barrier_mutex; pthread_cond_t barrier_cond; int nthread; // Number of threads that have reached this round of the barrier int round; // Barrier round } bstate; static void barrier_init(void) { assert(pthread_mutex_init(&bstate.barrier_mutex, NULL) == 0); assert(pthread_cond_init(&bstate.barrier_cond, NULL) == 0); bstate.nthread = 0; } static void barrier() { pthread_mutex_lock(&bstate.barrier_mutex); if (!(bstate.nthread)) { bstate.nthread++; pthread_cond_wait(&(bstate.barrier_cond), &(bstate.barrier_mutex)); } else { bstate.nthread--; bstate.round++; pthread_cond_broadcast(&(bstate.barrier_cond)); } pthread_mutex_unlock(&bstate.barrier_mutex); } static void * thread(void *xa) { long n = (long) xa; long delay; int i; for (i = 0; i < 20000; i++) { int t = bstate.round; assert (i == t); barrier(); usleep(random() % 100); } } int main(int argc, char *argv[]) { pthread_t *tha; void *value; long i; double t1, t0; if (argc < 2) { fprintf(stderr, "%s: %s nthread\n", argv[0], argv[0]); exit(-1); } nthread = atoi(argv[1]); tha = malloc(sizeof(pthread_t) * nthread); srandom(0); barrier_init(); for(i = 0; i < nthread; i++) { assert(pthread_create(&tha[i], NULL, thread, (void *) i) == 0); } for(i = 0; i < nthread; i++) { assert(pthread_join(tha[i], &value) == 0); } printf("OK; passed\n"); }