向条件变量发送信号时必须保持锁定吗?

Must lock be held when signaling conditional variable?

好的。这里的示例是使用 c.

中的 pthread lib 提供的

在课本中我看到了下面的代码:

//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

此代码运行良好。我只是想知道以下代码是否也有效?

//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);//signal the conditional variable but the lock is not held

以下代码的优缺点是什么?

PS。假设协作线程有代码:

//for thread 1
pthread_mutex_lock(&lock);
while(!should_wake_up)
    pthread_cond_wait(&cond, &lock);
pthead_mutex_unlock(&lock);

PS2。我遇到了一些其他问题,它指出如果我们不希望信号丢失,我们必须使用 lock 来确保关联的谓词(在本例中为 should_wake_up)在锁在线程 1 中。在这种情况下,这似乎不是问题所在。 Link 到 post: [1]: signal on condition variable without holding lock。我认为他的问题是他忘记了锁定。但是我的问题不一样。

对于正常使用,您可以在向条件变量发出信号之前解锁互斥量。

互斥锁保护共享状态(在本例中为 should_wake_up 标志)。如果在修改共享状态时锁定了互斥量,并且在检查共享状态时,可以在不锁定互斥量的情况下调用 pthread_cond_signal,一切都会按预期进行。

在大多数情况下,我会 建议 调用 pthread_cond_signal 调用 pthread_mutex_unlock 之后调用 pthread_mutex_unlock 作为轻微的性能改进.如果你在 pthread_mutex_unlock 之前调用 pthread_cond_signal 那么等待线程可以在互斥量解锁之前被信号唤醒,所以等待线程必须回到睡眠状态,因为它阻塞在互斥量上仍然由信号线程持有。