我正在尝试使用boost :: atomic在linux上进行多线程同步。
但是,结果并不一致。
任何帮助将不胜感激。
感谢
#include <boost/bind.hpp>
#include <boost/threadpool.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
#include <boost/atomic.hpp>
boost::atomic<int> g(0) ;
void f()
{
g.fetch_add(1, boost::memory_order_relaxed);
return ;
}
const int threadnum = 10;
int main()
{
boost::threadpool::fifo_pool tp(threadnum);
for (int i = 0 ; i < threadnum ; ++i)
tp.schedule(boost::bind(f));
tp.wait();
std::cout << g << std::endl ;
return 0 ;
}
答案 0 :(得分:2)
我并不熟悉boost线程库,或者说boost :: threadpool,但是在我看来,当你访问g的值时线程没有必要完成,所以你会在零和之间得到一些值。 10。
这是你的程序,修改为使用标准库,插入了连接,以便在g的输出之前发生提取添加。
std::atomic<int> g(0);
void f() {
g.fetch_add(1, std::memory_order_relaxed);
}
int main() {
const int threadnum = 10;
std::vector<std::thread> v;
for (int i = 0 ; i < threadnum ; ++i)
v.push_back(std::thread(f));
for (auto &th : v)
th.join();
std::cout << g << '\n';
}
如果您的程序即使添加了tp.wait()
仍然不一致,那就太令人费解了。添加应该在线程结束之前发生,我认为线程结束将与tp.wait()
同步,这在读取之前发生。所以所有添加都应该在g打印之前发生,即使你使用memory_order_relaxed,所以打印的值应该是10。
答案 1 :(得分:1)
以下是一些可能有用的示例:
基本上,你试图用“锁定”“保护”“关键区域”。
您可以设置或取消设置信号量。
或者你可以“交换”一个提升“原子”变量。例如(来自上面的链接):
class spinlock {
private:
typedef enum {Locked, Unlocked} LockState;
boost::atomic<LockState> state_;
public:
spinlock() : state_(Unlocked) {}
lock()
{
while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) {
/* busy-wait */
}
}
unlock()
{
state_.store(Unlocked, boost::memory_order_release);
}
};