如何迭代boost特定于线程的指针

时间:2015-06-16 11:37:03

标签: c++ multithreading boost-thread thread-local-storage thread-specific-storage

我有一个多线程应用程序。每个线程在其自己的本地存储中初始化struct数据类型。一些元素被添加到struct类型变量内的向量中。在程序结束时,我想迭代这些线程本地存储并将所有结果一起添加。如何迭代线程特定的指针,以便我可以将多线程的所有结果一起添加?

提前致谢。

boost::thread_specific_ptr<testStruct> tss;

size_t x = 10;

void callable(string str, int x) {
    if(!tss.get()){
        tss.reset(new testStruct);
        (*tss).xInt.resize(x, 0);
    }
    // Assign some values to the vector elements after doing some calculations
}

示例:

#include <iostream>
#include <vector>
#include <boost/thread/mutex.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#define NR_THREAD 4
#define SAMPLE_SIZE 500

using namespace std;

static bool busy = false;

struct testStruct{
    vector<int> intVector;
};

boost::asio::io_service ioService;
boost::thread_specific_ptr<testStruct> tsp;
boost::condition_variable cond;
boost::mutex mut;

void callable(int x) {
    if(!tsp.get()){
        tsp.reset(new testStruct);
    }

    (*tsp).intVector.push_back(x);

    if (x + 1 == SAMPLE_SIZE){
        busy = true;
        cond.notify_all();
    }
}

int main() {
    boost::thread_group threads;
    size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run;
    boost::asio::io_service::work work(ioService);

    for (short int i = 0; i < NR_THREAD; ++i) {
        threads.create_thread(boost::bind(run, &ioService));
    }

    size_t iterations = 10;
    for (int i = 0; i < iterations; i++) {
        busy = false;

        for (short int j = 0; j < SAMPLE_SIZE; ++j) {
            ioService.post(boost::bind(callable, j));
        }

        // all threads need to finish the job for the next iteration
        boost::unique_lock<boost::mutex> lock(mut);
        while (!busy) {
            cond.wait(lock);
        }
        cout << "Iteration: " << i << endl;
    }

    vector<int> sum(SAMPLE_SIZE, 0);    // sum up all the values from thread local storages

    work.~work();
    threads.join_all();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

所以,在我没有考虑过这个问题之后,我想出了这样一个解决方案:

void accumulateTLS(size_t idxThread){

    if (idxThread == nr_threads)   // Suspend all the threads till all of them are called and waiting here
    {
        busy = true;
    }

    boost::unique_lock<boost::mutex> lock(mut);
    while (!busy)
    {
        cond.wait(lock);
    }

    // Accumulate the variables using thread specific pointer

    cond.notify_one();
}

使用boost io_service,可以在初始化线程后更改可调用函数。因此,在完成所有计算之后,我将使用可调用函数accumulateTLS(idxThread)将作业(尽可能多的线程数)发送到io服务。 N个作业被发送到N个线程,累积过程在accumulateTLS方法内完成。

P.S。而不是工作。应该使用work(),work.reset()。