iol*_*olo 13 c++ multithreading locking c++11
有没有办法确保被阻塞的线程以被阻止的顺序被唤醒?我在某处读到这将被称为"强锁",但我没有找到任何资源.
在Mac OS X上,可以设计一个FIFO队列来存储被阻塞线程的所有线程ID,然后使用nifty函数pthread_cond_signal_thread_np()
唤醒一个特定线程 - 这显然是非标准和非可移植的.
我能想到的一种方法是使用一个类似的队列,并在unlock()
此时向broadcast()
所有线程发送一个并让它们检查哪一个是下一个.
但这会产生很多开销.
解决问题的方法是将packaged_task发送到队列并让它按顺序处理它们.但对我而言,这似乎更像是一种解决方案而非解决方案.
编辑:
正如评论所指出的,这个问题可能听起来无关紧要,因为原则上没有保证锁定尝试的顺序.
作为澄清:
我有一些我称之为ConditionLockQueue的东西,它与Cocoa库中的NSConditionLock类非常相似,但是它维护了一个被阻塞的线程的FIFO队列而不是一个或多或少的随机池.
基本上任何线程都可以"排队"(有或没有特定'条件'的要求 - 一个简单的整数值 - 要满足).然后将该线程放在队列上并阻塞,直到它成为满足条件的队列中最前面的元素.
这提供了一种非常灵活的同步方式,我发现它在我的程序中非常有用.
现在我真正需要的是一种唤醒具有特定id的特定线程的方法.
但这些问题几乎是相似的.
Chr*_*odd 14
很容易构建一个使用编号票证的锁定对象,以确保其完全公平(锁定是在线程首先尝试获取它的顺序中授予的):
#include <mutex>
#include <condition_variable>
class ordered_lock {
std::condition_variable cvar;
std::mutex cvar_lock;
unsigned int next_ticket, counter;
public:
ordered_lock() : next_ticket(0), counter(0) {}
void lock() {
std::unique_lock<std::mutex> acquire(cvar_lock);
unsigned int ticket = next_ticket++;
while (ticket != counter)
cvar.wait(acquire);
}
void unlock() {
std::unique_lock<std::mutex> acquire(cvar_lock);
counter++;
cvar.notify_all();
}
};
Run Code Online (Sandbox Code Playgroud)
编辑
修复奥拉夫的建议:
#include <mutex>
#include <condition_variable>
#include <queue>
class ordered_lock {
std::queue<std::condition_variable> cvar;
std::mutex cvar_lock;
bool locked;
public:
ordered_lock() : locked(false) {};
void lock() {
std::unique_lock<std::mutex> acquire(cvar_lock);
if (locked) {
cvar.emplace();
cvar.back().wait(acquire);
} else {
locked = true;
}
}
void unlock() {
std::unique_lock<std::mutex> acquire(cvar_lock);
if (cvar.empty()) {
locked = false;
} else {
cvar.front().notify_one();
cvar.pop();
}
}
};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4170 次 |
最近记录: |