1

我正在实现条件变量的等待操作。我的条件变量有一个结构。到目前为止,我的结构有一个监视器、一个队列和一个自旋锁。但我不确定条件变量本身是否应该有一个队列。我的通知如下所示:

 void uthread_cv_notify (uthread_cv_t* cv) {
     uthread_t* waiter_thread;
     spinlock_lock(&cv->spinlock);
     waiter_thread   = dequeue (&cv->waiter_queue);
     if(waiter_thread)
     {
        uthread_monitor_exit(cv->mon);
        uthread_stop(TS_BLOCKED);
        uthread_monitor_enter(cv->mon);
        spinlock_unlock(&cv->spinlock);
     }
} 

但我想知道在通知函数或等待函数中我是否应该在监视器的等待队列中入队和出队?

谢谢

4

2 回答 2

0

So why do you need an extra queue? You are already storing all the threads that need to be notified.

Also, you probably want to do something like this:

void uthread_cv_notify (uthread_cv_t* cv) {
     uthread_t* waiter_thread;
     spinlock_lock(&cv->spinlock);
     waiter_thread   = dequeue (&cv->waiter_queue);
     if(waiter_thread)
     {
        uthread_monitor_exit(cv->mon);
        uthread_stop(TS_BLOCKED);
        uthread_monitor_enter(cv->mon);
     }
     spinlock_unlock(&cv->spinlock);
} 

This will ensure that the spin lock is always released.

于 2012-03-28T20:01:32.110 回答
0

信号操作(您调用 notify)不应要求输入监视器。这是低效的。

似乎您正在尝试实现一些笨拙的老式条件/监视器系统,其中“通知”的调用者必须在监视器内,并且可以保证如果线程正在等待,则该线程在“通知”调用者返回到监视器。(并且该等待线程也不必循环重新测试条件。)

这可能是 CAR Hoare 最初描述监视器和条件的方式,但这种形式主义在现代多处理器系统上是不切实际/效率低下的,而且对于没有与低级调度程序极其紧密集成的线程实现(能够精确控制何时运行哪个线程,因此没有关于谁首先获得互斥锁的竞争:例如,能够将一个线程从一个等待队列转移到另一个等待队列,等等)

请注意您如何将监视器的关键部分扩展到spinlock_lock操作和dequeue操作上。这些都不属于监控之下。自旋锁是独立的,队列由自旋锁保护,而不是由监视器保护。监视器应该只保护用户代码的共享变量(等待操作的特殊原子属性)。

于 2012-03-29T03:08:33.723 回答