我一直在尝试用STL实现C ++线程池,该线程池接收队列中的任务并将任务分派给线程以执行。按下和弹出时,队列使用原子自旋锁,并且使用以下代码,一切似乎都可以正常工作:
void push(const std::function<bool()>& func){
while(in_use.exchange(true, std::memory_order_acquire));
//Actually push the queue, deal with possible exceptions, etc.
in_use.store(false, std::memory_order_release);
}
std::function<bool()> pop(){
while(in_use.exchange(true, std::memory_order_acquire));
//Actually push the queue, deal with possible exceptions, etc.
in_use.store(false, std::memory_order_release);
}
.....//other functions for determining size, etc.
后来我认为std :: this_thread :: yield在循环中可能是个不错的选择。
(当我进行测试时,我的PC处于工作状态,当将进程执行优先级设置为“实时...”时,该任务会将同一任务推入池中,然后轮询该池。)
但是,当我更改行
while(in_use.exchange(true, std::memory_order_acquire));
到
while(in_use.exchange(true, std::memory_order_acquire)) std::this_thread::yield();
在相同条件下(任务正在将同一任务推入池中,任务比池中的线程更多。),没有其他修改,所有推入池主队列的线程都陷入死锁状态,所有等待几分钟后,释放变量。
我想知道yield函数对可能导致此问题的原子变量操作到底能做些什么。
PS:CPU硬件:英特尔酷睿i5,操作系统Windows 10 1803,VS 2017 SDK版本10.0.17763.0。