pthreads 中的条件变量并释放多个锁

Conditional variables in pthreads and releasing multiple locks

本文关键字:释放 变量 条件 pthreads      更新时间:2023-10-16

对不起,如果这是一个微不足道的问题。但我在任何地方都找不到答案。我正在编写一个使用 pthreads 的程序。一个线程获取锁(互斥锁),然后尝试将数据推送到同步缓冲区中。缓冲区有自己的互斥锁,一旦调用 push() 方法就会被获取。

如果缓冲区已满并且线程需要等待条件变量,等待调用是否会释放所有获取的锁?还是只会释放与条件变量关联的锁(恰好是最后一个获取的锁)?如果是后者,如果另一个线程需要获取第一个锁,如何避免死锁?

编辑:

我遇到的问题如下。我有两个线程,比如 AB。线程 A 有一个 for 循环,可将数据插入多个缓冲区。每次迭代都会将一个元素插入到其中一个缓冲区中。由于这是一个线程,因此它会在线程的另一个外部循环中连续执行此循环。当 B 被激活时,它会操纵这些缓冲区。但是,如果 A 在执行 for 循环的过程中被调度程序打断,则 B 不得在缓冲区上运行。因此,我使用互斥锁来锁定 A 中的关键部分,即 for 循环。

编辑-2:

我一直在考虑这个问题。我的问题的答案肯定不会是缓冲区的条件变量也会释放第一个锁。这意味着首先甚至不需要第一把锁。如果负责从缓冲区中删除元素的使用者线程(不同于线程 B)正在正常执行其工作,则线程 A 将在某个时候恢复,并且 for 循环将完成。因此,我的问题必须在那里。我会仔细看看并更新。

pthread_cond_wait()将仅释放您传递给它的互斥锁,在您的情况下,这将是缓冲区在push()调用中先前获取的互斥锁。

听起来你的情况可能会陷入僵局,但这是你的高级设计的结果。 如果在线程 A 运行其for()循环时不允许线程 B 执行,但在该for()循环中,线程 A 可能必须等待线程 B 消耗一些数据进行处理,则死锁是不可避免的。

您需要更新您的设计以解决此问题。 一种可能性是向同步缓冲区添加一个reserve()函数,为后续push()保留空间,但不添加任何数据。 然后,您的线程 A 可以在不持有外部互斥锁的情况下遍历并保留所需的空间(因为它尚未添加线程 B 可见的任何数据) - 如果它必须等待线程 B 消耗一些数据,它将在此处执行此操作。 一个它保留了它需要的所有空间,然后它可以锁定外部互斥锁并推送数据 - 这保证不必等待线程 B,因为空间已经被保留了。