我正在通过REMZI进行并发部分,并且在浏览互斥部分时,我对此感到困惑:
为了避免繁忙等待,互斥实现采用park()
/ unpark()
机制(在Sun OS上),它将一个等待线程放入一个带有线程ID的队列中。稍后在pthread_mutex_unlock()
期间,它会从队列中删除一个线程,以便调度程序可以选择它。同样,Futex(Linux上的互斥实现)的实现使用相同的机制。
目前还不清楚队列在哪里。它是在正在运行的进程的地址空间还是在内核的某个地方?
我的另一个疑问是条件变量。 pthread_cond_wait()
和pthread_cond_signal()
使用普通signals并等待方法,还是使用它的某些变体?
答案 0 :(得分:4)
怀疑1:但是,我仍然不清楚队列究竟在哪里。它是在正在运行的进程的地址空间还是在内核的某个地方。
每个互斥锁都有一个在内核地址空间中维护的关联数据结构,在Linux中它是futex。该数据结构具有关联的等待队列,来自不同进程的线程可以排队并等待唤醒,请参阅futex_wait
kernel function。
怀疑2:我对条件变量的另一个疑问是,pthread_cond_wait()和pthread_cond_signal()是否使用正常信号和等待方法或者它们使用了它的一些变体。
Modern Linux不使用信号进行条件变量信令。有关详细信息,请参阅NPTL: The New Implementation of Threads for Linux:
将快速用户空间锁定(futex)添加到内核中,可以完全重新实现互斥锁和其他同步机制,而无需借助于线程间信令。反过来,通过向内核引入抢占式调度,使futex成为可能。