【发布时间】:2013-01-25 08:48:09
【问题描述】:
有没有办法确保被阻塞的线程按照被阻塞的顺序唤醒?我在某处读到这将被称为“强锁”,但我没有找到任何资源。
在 Mac OS X 上,可以设计一个 FIFO 队列来存储阻塞线程的所有线程 ID,然后使用漂亮的函数 pthread_cond_signal_thread_np() 来唤醒一个特定的线程——这显然是非标准且不可移植的。
我能想到的一种方法是使用类似的队列,并在 unlock() 点向所有线程发送 broadcast() 并让它们检查哪一个是下一个队列。
但这会导致大量开销。
解决该问题的一种方法是将 packaged_task 发送到队列并让它按顺序处理它们。但这对我来说更像是一种解决方法而不是解决方案。
编辑:
正如 cmets 所指出的,这个问题听起来可能无关紧要,因为原则上没有保证锁定尝试的顺序。
作为澄清:
我有一个我称之为 ConditionLockQueue 的东西,它与 Cocoa 库中的 NSConditionLock 类非常相似,但它维护一个阻塞线程的 FIFO 队列,而不是一个或多或少的随机池。
基本上任何线程都可以“排队”(有或没有特定“条件”的要求 - 一个简单的整数值 - 要满足)。然后线程被放置在队列中并阻塞,直到它是队列中满足条件的最前面的元素。
这提供了一种非常灵活的同步方式,我发现它在我的程序中非常有用。
现在我真正需要的是一种唤醒具有特定 ID 的特定线程的方法。
但这些问题几乎都是一样的。
【问题讨论】:
-
请解释为什么需要保持顺序...以及如何保证线程将按照您希望它们到达的顺序到达锁。
-
嗯,首先它很有趣!然后它正好适合我的程序;)我可以将它设计为更加异步,但如果有另一种方式会更简单。
-
我的观点是,即使你得到了这个解决方案,它也是没有意义的,因为你需要保证线程以某种顺序到达锁,而如果没有先前的同步,你就无法做到这一点。我可能是错的,所以我要求解释你的设计。
-
好吧,如果你真的想这样做,我认为最好的办法是在锁定机制中内置一个“谁是下一个”队列。但我仍然认为寻找新问题似乎是一个问题,所以现在你有两个问题...... ;)
-
所以在某些时候线程必须再次同步并“单线程”执行?为什么不在你现在要锁定的地方,将
std::functions(或类似的)放在一个FIFO队列上,然后只处理那个单线程,同时在线程中等待,直到那个函数完成?它会产生相同的效果,您只需要锁定 FIFO 队列,并且可能需要一些条件/唤醒/未来机制来继续线程。
标签: c++ multithreading c++11 locking