2019.9.10 6.828 barrier

閒的蛋疼作了一個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");
}
相關文章
相關標籤/搜索