如何使用原子基元编写自己的条件变量

时间:2010-09-14 14:46:37

标签: c++

我需要编写自己的条件变量实现,就像pthread_cond_t。

我知道我需要使用编译器提供的原语,如__sync_val_compare_and_swap等。

有人知道我该怎么做。

THX

3 个答案:

答案 0 :(得分:9)

条件变量的正确实施是 HARD 。使用众多库中的一个(例如boost,pthreads-win32,我的just :: thread库)

你需要:

  • 保留等待线程列表(这可能是“虚拟”列表而不是实际数据结构)
  • 确保线程等待您原子解锁等待线程拥有的互斥锁,并在该线程进入阻塞OS调用之前将其添加到列表中
  • 确保在通知条件变量时,其中一个等待的线程被唤醒,而不是等待稍后的线程
  • 确保广播条件变量时,那时等待的所有线程都被唤醒,而不是任何稍后等待的线程。
  • 加上我刚才想不到的其他问题。

详细信息因操作系统而异,因为您依赖于OS阻塞/唤醒原语。

答案 1 :(得分:3)

  

我需要编写自己的条件变量实现,就像pthread_cond_t。

无法仅使用compare-and-swap等原子基元来实现条件变量。

cond vars的生命目的是为应用程序提供访问进程/线程调度程序的灵活机制:将线程置于休眠状态并将其唤醒。

原子操作由CPU实现,而进程/线程调度程序是操作系统区域。如果没有一些支持系统调用(或使用现有同步原语进行仿真),实现cond vars是不可能的。

Edit1。我知道并且可以指出的唯一明智的例子是可以找到here的历史Linux pthread库的实现 - 例如version from 1997。实现(在condvar.c文件中找到)相当容易阅读,但也强调了实现cond变量的要求。 Spinlocks(使用test-and-set op)用于同步,POSIX signals用于将线程置于休眠状态并将其唤醒。

答案 2 :(得分:1)

这取决于您的要求。如果您没有进一步的要求,并且如果您的进程可能消耗100%的可用CPU时间,那么您有罕见机会进行试验并尝试不同的互斥和条件变量 - 只需尝试一下,并且了解细节。好极了。

但实际上,你真的被操作系统所束缚,因此你对操作系统线程原语感到着迷,因为它们代表了唯一的控制 - 是 - 进程/线程/ cpu资源使用!因此,在这种情况下,您甚至没有机会实现您的OWN条件变量 - 如果它们不是基于原始的,操作系统为您提供!

所以...仔细检查你的 环境 ,你控制什么?你不控制什么?什么是有道理的?