pthread_cond_wait()如何与互斥锁解耦?

huangapple go评论62阅读模式
英文:

How can pthread_cond_wait() be decoupled with mutex?

问题

I've been thinking about the logic behind condition variable for a while, and getting comfortable with most common questions associated with it.

Basically, if we do something like:

mutex.lock()
while(!predicate()){
    mutex.unlock();
    pthread_cond_wait(&cv); // with mutex decoupled, no mutex is passed in I guess.
    mutex.lock();
}
mutex.unlock();

The window between unlock() and wait() is something we need to eliminate, and that's pretty much why cv exists in the first place.

Then I found this:

> ### Features of Mutexes and Condition Variables
>
> It had been suggested that the mutex acquisition and release be
> decoupled from condition wait. This was rejected because it is the
> combined nature of the operation that, in fact, facilitates realtime
> implementations. Those implementations can atomically move a
> high-priority thread between the condition variable and the mutex in a
> manner that is transparent to the caller. This can prevent extra
> context switches and provide more deterministic acquisition of a mutex
> when the waiting thread is signaled. Thus, fairness and priority
> issues can be dealt with directly by the scheduling discipline.
> Furthermore, the current condition wait operation matches existing
> practice.

(https://linux.die.net/man/3/pthread_cond_wait)

I just don't understand how pthread_cond_wait() can be decoupled with the mutex usage.

Hope someone can show me how can it be achieved, Or:
Do I misunderstand the meaning of "decouple" in the comment?

英文:

I've been thinking about the logic behind condition variable for a while, and getting comfortable with most common questions associated with it.

Basically, if We do something like:

mutex.lock()
while(!predicate()){
    mutex.unlock();
    pthread_cond_wait(&cv); // with mutex decoupled, no mutex is passed in I guess.
    mutex.lock();
}
mutex.unlock();

The window between unlock() and wait() is something we need to eliminate, and that's pretty much why cv exists in the first place.

Then I found this:

> ### Features of Mutexes and Condition Variables
>
> It had been suggested that the mutex acquisition and release be
> decoupled from condition wait. This was rejected because it is the
> combined nature of the operation that, in fact, facilitates realtime
> implementations. Those implementations can atomically move a
> high-priority thread between the condition variable and the mutex in a
> manner that is transparent to the caller. This can prevent extra
> context switches and provide more deterministic acquisition of a mutex
> when the waiting thread is signaled. Thus, fairness and priority
> issues can be dealt with directly by the scheduling discipline.
> Furthermore, the current condition wait operation matches existing
> practice.

(https://linux.die.net/man/3/pthread_cond_wait)

I just don't understand how pthread_cond_wait() can be decoupled with the mutex usage.

Hope someone can show me how can it be achieved, Or:
Do I misunderstand the meaning of "decouple" in the comment?

答案1

得分: 1

这可以在协作式多任务系统中实现,在这种系统中,有一个隐式的全局互斥锁。隐式全局互斥锁是只有一个线程在一次运行,直到它放弃处理器。在这种系统中,您可以使用条件变量而无需使用显式互斥锁。条件等待操作通过确保调用线程在放弃处理器之前准备好等待来实现原子性。

看起来这段文字来自POSIX标准; 它出现在pthread_cond_wait描述的合理性段落中。

确定POSIX标准中任何东西的含义最可靠的方法是联系Austin小组,也许可以加入邮件列表。

我怀疑“分离”所指的并不是条件不能在没有互斥锁的情况下使用,而是API以某种方式允许应用程序独立控制互斥锁,以便在等待条件时需要多个步骤。

多步等待的示例,其中应用程序控制锁,可以在Linux内核中找到,明确使用等待队列。要在等待队列上等待,线程需要持有某些相关的锁。在该锁下,它将自身添加到队列并通过将其状态更改为休眠状态来准备等待。然后它释放锁,并调用调度程序以被挂起。经过调度程序调用后,线程将自身从队列中移除。

使用更复杂的多步API有一些优势,例如能够在多个等待队列中注册。想象一下,如果我们有一个APIpthread_cond_wait_multiple,我们可以在其中指定一个互斥锁和多个条件变量,以便线程在其中任何一个广播时唤醒。您无法使用pthread_cond_wait构建这样的功能,但分离的API可能会使其成为可能。

英文:

It can be achieved in a cooperative multitasking system, where you have an implicit global mutex. The implicit global mutex is the fact that only one thread runs at a time until it yields the processor. In such a system, you can have condition variables without any explicit mutex in sight. The condition wait operation achieves atomicity by ensuring that the calling thread is prepared for the wait before giving up the processor.

It looks like the text from that manual page is cribbed from the POSIX standard; it appears in the Rationale paragraphs of the description of pthread_cond_wait.

The surest way to determine what anything means in the POSIX standard is to contact the Austin group perhaps by joining the mailing list.

I suspect what this means by "decoupled" is not that a condition not be used without a mutex but that the API somehow allow the application to control the mutex independently, such that waiting on a condition takes multiple steps.

An example of multi-step waiting where the application controls the lock is found in the Linux kernel, in the explicit use of wait queues. To wait on a wait queue, the thread holds some relevant lock. Under that lock, it adds itself to the queue and prepares to wait by changing its state to a sleep state. Then it releases the lock, and calls the scheduler to be suspended. Once past the scheduler call, the thread removes itself from the queue.

There are some advantages to the more complicated, multi-step API, such as being able to register in multiple wait queues. Imagine we had an API pthread_cond_wait_multiple where we specify a mutex, and multiple condition variables, such that the thread wakes up if any of them are broadcast. You can't build that with pthread_cond_wait, but a decoupled API could make it possible.

huangapple
  • 本文由 发表于 2023年4月19日 17:47:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76053070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定