0

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

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

编辑:

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

编辑2:

我一直在考虑。我的问题的答案肯定不会是缓冲区的条件变量也释放第一个锁。这意味着最初甚至不需要第一个锁。如果负责从缓冲区中删除元素的消费者线程(不同于线程B )正在正常工作,线程A将在某个点恢复并且for循环将完成。因此,我的问题一定出在那儿。我会仔细看看并更新。

4

1 回答 1

0

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

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

您将需要更新您的设计以解决此问题。一种可能性是向reserve()您的同步缓冲区添加一个函数,为后续缓冲区保留空间push(),但不添加任何数据。然后,您的线程 A 可以通过并保留它所需的空间,而无需保留外部互斥锁(因为它还没有添加任何对线程 B 可见的数据) - 如果它必须等待线程 B 消耗一些数据,它会这样做这里。一是它保留了它需要的所有空间,然后它可以锁定外部互斥体并推送数据——这保证了不必等待线程 B,因为空间已经被保留了。

于 2013-10-29T03:46:35.267 回答