正确使用原子<T>
Correctly using atomic<T>
我目前正在为基于https://github.com/nbsdx/ThreadPool.这是我修改过的课程:
class ThreadPool
{
public:
explicit ThreadPool(int threadCount) :
_jobsLeft(0),
_bailout(false)
{
_threads = std::vector<std::thread>(threadCount);
for (int index = 0; index < threadCount; ++index)
{
_threads[index] = std::move(std::thread([this]
{
this->Task();
}));
}
}
void AddJob(std::function<void(void)> job)
{
{
std::lock_guard<std::mutex> lock(_queueMutex);
_queue.emplace(job);
}
{
std::lock_guard<std::mutex> lock(_jobsLeftMutex);
++_jobsLeft;
}
_jobAvailableVar.notify_one();
}
void JoinAll()
{
if (!_bailout)
{
_bailout = true;
_jobAvailableVar.notify_all();
for (auto& x : _threads)
{
if (x.joinable())
{
x.join();
}
}
}
}
void WaitAll()
{
std::unique_lock<std::mutex> lock(_jobsLeftMutex);
if (_jobsLeft > 0)
{
_waitVar.wait(lock, [this]
{
return _jobsLeft == 0;
});
}
}
private:
void Task()
{
while (!_bailout)
{
std::function<void(void)> job;
{
std::unique_lock<std::mutex> lock(_queueMutex);
_jobAvailableVar.wait(lock, [this]
{
return _queue.size() > 0 || _bailout;
});
if (_bailout)
{
return;
}
job = _queue.front();
_queue.pop();
}
job();
{
std::lock_guard<std::mutex> lock(_jobsLeftMutex);
--_jobsLeft;
}
_waitVar.notify_one();
}
}
std::vector<std::thread> _threads;
std::queue<std::function<void(void)>> _queue;
int _jobsLeft;
std::atomic<bool> _bailout;
std::condition_variable _jobAvailableVar;
std::condition_variable _waitVar;
std::mutex _jobsLeftMutex;
std::mutex _queueMutex;
};
我对以下内容感到困惑,如果有任何建议,我将不胜感激:
- 如何使
_bailout
的使用真正原子化?我玩了atomic_flag
,但在这种情况下无法使其发挥作用 - 在没有所有这些锁的情况下,使用
atomic<int>
是否可以使_jobsLeft
正常工作?我对原始线程池有一个问题,在极少数情况下WaitAll()
不会正确返回。它现在运行得很好,但我觉得它浪费了性能
编辑:此处提供带普通锁的最终版本:https://github.com/stfx/ThreadPool2
看看原子方法:http://en.cppreference.com/w/cpp/atomic/atomic
您应该使用load方法以原子方式读取该值。但是,请注意以下内容不是原子性的。
if (!_bailout)
{
_bailout = true;
有一种方法可以执行这些比较和价值交换。请参见compare_exchange_weak方法。对于jobCount,可以使用atomic。++和--是原子。
但是,请注意,原子只是一个单独的方法调用,调用后情况可能会发生变化。您仍然需要一个同步的队列,为此您需要一个锁。它不需要是标准的操作系统锁,您可以使用原子变量创建锁(使用store和compare_exchange_weak方法)。请参阅以下帖子:https://webkit.org/blog/6161/locking-in-webkit/
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中