3

Linuxでマルチスレッド同期を行うためにboost::atomicを使用しようとしています。

しかし、結果は一貫していません。

どんな助けでも大歓迎です。

ありがとう

#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 ;
  }
4

2 に答える 2

2

特にブースト スレッド ライブラリ、または boost::threadpool について詳しくは知りませんが、g の値にアクセスするときにスレッドが必ずしも完了していないように見えるため、0 から 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()ます。したがって、memory_order_relaxed を使用していても、すべての追加は g が出力される前に行われる必要があるため、出力される値は 10 になるはずです。

于 2012-06-10T05:25:42.463 に答える
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);
  }
};
于 2012-06-10T05:32:24.447 に答える