【问题标题】:How can I create a Barrier in c++?如何在 C++ 中创建屏障?
【发布时间】:2018-07-20 15:21:41
【问题描述】:

我的程序中有 4 个线程。我想全部执行一次,一旦全部执行完毕,我只想进入下一次执行迭代。

我得到了一个堆栈溢出代码,它在 C++ 中实现了 boost::barrier 函数。但这似乎对我不起作用。对于一次迭代,它工作正常。但是对于下一次迭代,程序执行只是挂起。

//这是我的顶级代码:

#include <iostream>
#include <stdio.h>
#include <thread>
#include "abc_func.hpp"
#include <vector>
using namespace std;

int main() {
    abc obj1;
        obj1.num_threads(4);
    std::thread t1([&obj1](){
        for (int i=0; i<5; i++) {
        while (!obj1.abc_write(1));
        };
    });
    std::thread t2([&obj1](){
        for (int i=0; i<5; i++) {
        while (!obj1.abc_read(2));
        };
    });
    std::thread t3([&obj1](){
        for (int i=0; i<5; i++) {
        while (!obj1.abc_write(3));
        };
    });
    std::thread t4([&obj1](){
        for (int i=0; i<5; i++) {
        while (!obj1.abc_read(4));
        };
    });
    t1.join();
    t2.join();
    t3.join();
        t4.join();


//  cout << "done: " << obj1.done << endl;

    // cout << "done: " << obj2.done << endl;

    // cout << "wr_count: " << obj1.wr_count << endl;
    return 0;   
}

// 这里是 abc_func.hpp

#include <iostream>
#include <stdio.h>
#include <thread>
#include <barrier.hpp>

using namespace std;
class abc {
    size_t n_threads;

    public:
    abc() : n_threads(0) {};

        void num_threads (size_t l) {
          n_threads = l;
        }

    Barrier task_bar{n_threads};

    bool abc_write (auto id) {
          thread_local int wr_count = 0;
          if (wr_count == 1) {
            std::cout << "write thread waiting" << id << endl;
            task_bar.Wait();
            wr_count = 0;
          };
      std::cout << "write thread running " << id << endl;
          ++wr_count;
      return true;
    }

    bool abc_read (auto id) {
          thread_local int rd_count=0;
          if (rd_count == 1) {
            std::cout << "read thread waiting" << id << endl;
            task_bar.Wait();
            rd_count = 0;
          };
      std::cout << "read thread running " << id << endl;
          ++rd_count;
      return true;
    }

};

//和我在堆栈溢出时得到的屏障类代码

#include <thread>
#include <condition_variable>
#include <mutex>
#include <iostream>
#include <stdio.h>

class Barrier {
public:
    explicit Barrier(std::size_t iCount) : 
      mThreshold(iCount), 
      mCount(iCount), 
      mGeneration(0) {
    }

    void Wait() {
        std::unique_lock<std::mutex> lLock{mMutex};
        auto lGen = mGeneration;
        if (!--mCount) {
            mGeneration++;
            mCount = mThreshold;
            mCond.notify_all();
        } else {
            mCond.wait(lLock, [this, lGen] { return lGen != mGeneration; });
        }
    }

private:
    std::mutex mMutex;
    std::condition_variable mCond;
    std::size_t mThreshold;
    std::size_t mCount;
    std::size_t mGeneration;
};

【问题讨论】:

  • 你为什么要“使用命名空间标准;”和“std::”同时...
  • 我还想知道为什么每个文件都有#include &lt;stdio.h&gt;,而似乎没有使用 stdio.h 中的任何内容。
  • @FredLarson 我只是从以前的文件中复制粘贴我的标题。
  • @Tushar 这两个都是不好的做法。 concurrency TS 为 C++ 添加了锁存器和屏障。如果你有足够新的编译器,你也许可以使用它。

标签: c++ multithreading c++11


【解决方案1】:

这段代码的问题在于成员

Barrier task_bar{n_threads};

一开始初始化一次,n_threads为0,以后调用时

obj1.num_threads(4);

屏障对象未更新。

当您也更新屏障时,它会按预期工作

class Barrier {
public:
// ...
    void num_threads(size_t n) {
        mThreshold = n;
        mCount = n;
    }
// ...
};

abc::num_threads()

void num_threads (size_t l) {
    n_threads = l;
    task_bar.num_threads(l);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 2011-01-04
    • 2011-12-28
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多