MIT 6.828 Homework: Thread and locking

任务:修改代码以实现对于每一个循环,让每一个线程都暂时阻塞直到所有线程都调用了barier函数

实际上就是实现一个屏障,当线程运行到屏障之前,会被暂时挂起,直到所有线程都到达屏障之后才会继续运行

而在原始的代码中,由于 barriers 函数中没有进行处理,sleep 较短时间的线程必定会比另一线程更早离开 barrier,进入下一个循环,从而发生错误。

在 barrier 函数的编写过程中需要维护两个变量,bstate.nthread 和 bstate.round。

  • bstate.thread 指示已到达屏障的线程的数量,用于判断是否应阻塞线程
  • bstate.round 指示当前的循环的数目,用于测试是否有线程提前离开了屏障。

进入 barrier 后,在加锁的基础上,首先将bstate.nthread 加 1,代表到达屏障的线程有多了一个;接着比较bstate.nthread 和 nthread 判断是否所有线程都已经到达屏障,如果没有全部到达,阻塞当先线程,加入等待队列,如果全部到达,bstate.round加 1,bstate.nthread置为 0 供下一轮循环使用,唤醒等待队列中的所有线程。

最终的barrier.c函数如下:

static void 
barrier()
{
  pthread_mutex_lock(&bstate.barrier_mutex);
  bstate.nthread++;
  if(bstate.nthread == nthread)
  {
    bstate.round++;
    bstate.nthread = 0;
    pthread_cond_broadcast(&bstate.barrier_cond);
  }
  else
  {
    pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);
  }
  pthread_mutex_unlock(&bstate.barrier_mutex);
}

最终测试结果如下:

❯ ./a.out 4
OK; passed
posted @ 2022-11-11 19:58  雪中的茶  阅读(86)  评论(0编辑  收藏  举报