c++ - 如何在其他线程等待时阻塞线程
问题描述
我有一个非常具体的问题要解决。我很确定世界上其他人已经遇到并解决了它,但我还没有找到任何解决方案。
这里是 :
- 我有一个线程从队列中弹出命令并异步执行它们
- 我可以从任何其他线程调用一个函数来同步执行命令,绕过队列机制,返回结果,并优先执行(在当前执行结束后)。
- 我有一个互斥锁来保护命令执行,因此一次只执行一个 问题是,对于一个简单的互斥锁,我无法确定在发生冲突时同步调用会在异步线程之前获得互斥锁。事实上,我们的测试表明分配非常不公平,异步线程总是获胜。
所以我想在有同步调用等待时阻塞异步线程。我事先不知道可以进行多少次同步调用,并且我不控制进行调用的线程(因此任何使用线程池的解决方案都是不可能的)。
我正在使用 C++ 和 Microsoft 库。我知道基本的同步对象,但也许有更高级的对象或方法适合我不知道的问题。
我对任何想法都持开放态度!
解决方案
好的,所以我终于有机会关闭它了。我尝试了这里和发布的链接中提出的一些解决方案。最后,我结合了一个用于命令执行的互斥锁和一个等待同步调用的计数器(当然,该计数器也受到互斥锁的保护)。异步线程在尝试获取互斥体之前检查计数器,并等待计数器为 0。此外,为了避免睡眠循环,我添加了一个在计数器设置为 0 时设置的事件。异步线程等待此事件在尝试获取互斥锁之前。
void incrementSyncCounter()
{
DLGuardThread guard(_counterMutex);
_synchCount++;
}
void decrementSyncCounter()
{
DLGuardThread guard(_counterMutex);
_synchCount--;
// If the counter is 0, it means that no other sync call is waiting, so we notify the main thread by setting the event
if(_synchCount == 0)
{
_counterEvent.set();
}
}
unsigned long getSyncCounter()
{
DLGuardThread guard(_counterMutex);
return _synchCount;
}
bool executeCommand(Command* command)
{
// Increment the sync call counter so the main thread can be locked while at least one sync call is waiting
incrementSyncCounter();
// Execute the command using mutex protection
DLGuardThread guard(_theCommandMutex);
bool res = command->execute();
guard.release();
// Decrement the sync call counter so the main thread can be unlocked if there is no sync call waiting
decrementSyncCounter();
return res;
}
void main ()
{
[...]
// Infinite loop
while(!_bStop)
{
// While the Synchronous call counter is not 0, this main thread is locked to give priority to the sync calls.
// _counterEvent will be set when the counter is decremented to 0, then this thread will check the value once again to be sure no other call has arrived inbetween.
while(getSyncCounter() > 0)
{
::WaitForSingleObject (_counterEvent.hEvent(), INFINITE);
}
// Take mutex
DLGuardThread guard(_theCommandMutex);
status = command->execute();
// Release mutex
guard.release();
}
}
推荐阅读
- java - 如何让一次只运行一个应用程序实例?
- google-cloud-platform - 网络端点组删除失败。错误:请求失败,出现未知错误
- c++ - C++:静态断言参数包匹配函数类型
- algorithm - 将 + 或 - 号分配给前 n 个自然数以获得给定值
- javascript - ReactJS - Javascript try/catch 在控制台中显示错误
- nginx - 无法让 nginx-vod-module 插件工作
- reactjs - 如何在reactjs中显示带有列表项(LI)的无序列表(UL)
- mysql - 使用嵌套 JSON_ARRAYAGG() 的无效组使用函数
- printing - 斑马打印机为 ZPL 有效负载中的设计标签提供键盘输入
- bash - 在 Bash 中提取除特定序列之外的所有字符