2017-04-01 11 views
0

私が知る限り、ラムダ内での静的ストレージの使用は合法です。基本的には、クロージャへのエントリ数をカウントします。ラムダ式、並行性と静的変数

#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

これを処理する最善の方法は、スレッドセーフカウンタを提供するstd::atomic<int>のインスタンスを取得することです。ラムダとその周囲のスコープの寿命に応じて、参照または共有ポインタでキャプチャすることができます。あなたの例を取るために

:スコープはコンテナに新しいスレッドを追加する、繰り返すこと、そしてそれは私がAVIDしたいグローバル変数でなければなりません、スレッドの開始を終えた後すぐに死んでしまうだろう周囲の

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"; 
    })); 
} 
+0

。さらに、全体の操作はテンプレートです。スコープが消滅した後にカウンターが提供されますか? – Swift

+1

@Swiftカウンターはワーカーコンテナと同じスコープでなければなりません。カウンタがグローバルである必要がある場合は、カウンターも同様にする必要があります。ワーカーコンテナに関する詳細がある場合は、詳細を追加することができます。 – user1937198

+0

ああ、持っています。だから、それぞれのフレーバー用のコンテナを格納するテンプレートクラスとそれらのためのカウンタを作成する必要があります。実際にラムダ内の静的なカウンターを宣言できないのはなぜですか? – Swift