Lambda表达式,并发和静态变量

时间:2017-04-01 12:30:34

标签: multithreading c++11 lambda concurrency

据我所知,在lambda中使用静态存储是合法的。本质上它会计算闭包中的条目数:

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>


typedef std::pair<int,int> mypair;

std::ostream &operator<< (std::ostream &os, mypair const &data) {
    return os << "(" << data.first << ": " << data.second << ") ";
}

int main()
{
    int n;
    std::vector<mypair> v;
    std::cin >> n;
    v.reserve(n);

    std::for_each(std::begin(v), std::end(v), [](mypair& x) {
        static int i = 0;
        std::cin >> x.second;
        x.first = i++;
    });

    std::for_each(std::begin(v), std::end(v), [](mypair& x) {
        std::cout << x;
    });

    return 0;
}   

假设我有一个容器'工人'的线程。

std::vector<std::thread> workers;
for (int i = 0; i < 5; i++) {
    workers.push_back(std::thread([]() 
    {
        std::cout << "thread #" << "start\n";
        doLengthyOperation();
        std::cout << "thread #" << "finish\n";
    }));
}

doLengthyOperation()中的代码包含并且自足操作,类似于新的流程创建。

如果我使用for_each加入他们,并且有问题的存储变量必须计算活动任务的数量,而不仅仅是条目数,这些计数器的可能实现是什么,如果我想避免依靠全局变量来避免别人搞砸它并允许自动支持线程的单独“风味”。

std::for_each(workers.begin(), workers.end(), [](std::thread &t) 
    {
        t.join();
    });

在完成线程启动后,周围的范围会很快死亡,可能会重复,可能会向容器添加新线程,这必须是全局变量,我想避免这种情况。更多,整个操作是一个模板

1 个答案:

答案 0 :(得分:1)

处理此问题的最佳方法是捕获std::atomic<int>的实例,该实例提供线程安全计数器。根据lambdas的生命周期和周围范围,您可能希望通过引用或共享指针捕获。

举个例子:

std::vector<std::thread> workers;
auto counter = std::make_shared<std::atomic<int>>(0);
for (int i = 0; i < 5; i++) {
    workers.push_back(std::thread([counter]() 
    {
        std::cout << "thread #" << "start\n";
        (*counter)++;
        doLengthyOperation();

        (*counter)--;
        std::cout << "thread #" << "finish\n";
    }));
}