2016-06-12 9 views
0

私のプログラマーでは、2つの別々のスレッドを実行したいと思います。これらのスレッドは、初期化され、メインスレッドで起動されます。このコンセプトはうまく動作しますが、一時停止していない間に子スレッドのいずれかにクールダウンを行わなければならないときにも、スレッドを一時停止するように見えます。一例として、本の別のスレッドでスレッドを実行できますか?

思う:

#include <iostream> 
#include <thread> 

class testClass { 
    static void grandchild(); 
    static void child(); 
public: 
    void parent(); 
}; 

void testClass::grandchild() { 
    //infinite loop of nothing; 
    while (true); 
} 

void testClass::child() { 
    //thread initalising and 
    std::thread grand(&testClass::grandchild); 
    std::cout << "before join" << std::endl; 
    grand.join(); 
    std::cout << "after join" << std::endl; 
} 

void testClass::parent() { 
    std::thread child(&testClass::child); 
    child.join(); 
} 
int main() { 
    testClass parentclass; 
    parentclass.parent(); 
} 

このプログラムの出力は今、これがまた起こる

http://puu.sh/ppTkR/e29221e1b8.png

である私はthis_thread ::一時停止sleep_forや他の機能を実行するとき糸。誰も私になぜこれが起こり、これを適切に実装するために可能なことがあるのか​​、これがC++で可能なのかを説明できますか?

+0

あなたが書くとき:*「それは一時停止されていない間、私は今、子スレッドの1にクールダウンをしなければならない」*、あなたは何をすべきか平均?この文脈で*クールダウン*とは何を意味しますか? – wally

+3

あなたは何を期待していますか?無限ループが終了するのを待っています。 –

+0

この例は、私が持っている問題を示すためのものです。 クールダウンとは、特定の時間の後に子スレッドの値を変更する必要があるということです。しかし、私は子スレッドが一時停止するのをやめたいのです – anon

答えて

3

.join()は、「そのスレッドが終了するまで待つ」ことを意味します。 parentchildchildを待ち、無限ループでスタックされているため、grandchildgrandchildが待機するため、何も起こりません。あなたは、あなたが生成したスレッドと結合するので、実質的にシングルスレッドを実行しています。

.join()の代わりに.detach()を使用するのを待つことはできませんでしたが、すべてのスレッドに参加してからmainに戻る必要があります。

+0

これは実際に私を助けました。与えられた例ではなく、私のプログラム内の子スレッドは(例外がスローされ、正しく捕らえられない限り)停止しません。 – anon

2

このプログラムは正しく動作しています。

  1. 「参加前」と表示されます。

  2. その後、無限while(1)ループが終了するまで待ちます。

  3. 無限の時間が経過すると、「結合後」と表示されます。

あなたは異なる動作をする場合は、おそらくあなたは、異なる振る舞いが何であるかを説明できます。

+0

私の最後のコメントでわかるように " \t この例は、私が持っている問題を実証することを目的としています。クールダウンでは、特定の時間の後に子スレッドの値を変更する必要があります。子スレッドが一時停止していない間に子スレッドで5秒後に値を変更したい場合は – anon

2

ここでは、孫のスレッドを使用して値を変更する前に3秒間待機する修正プログラムです。

子スレッドは実行を継続します。

#include <iostream> 
#include <thread> 
#include <atomic> 
#include <chrono> 

class testClass { 
public: 
    void grandchild(); 
    void child(); 
    void parent(); 
    std::atomic<int> value{0}; 
}; 

void testClass::grandchild() 
{ 
    std::this_thread::sleep_for(std::chrono::seconds(3)); 
    value = 5; 
} 

void testClass::child() 
{ 
    //thread initalising and 
    std::cout << "Starting grandchild thread.\n"; 
    std::thread grand(&testClass::grandchild,this); 
    //grand.detach(); // could detach so that a join() will not be required later 
    for (int x{0}; x<5; ++x) { 
     std::cout << x << '\t' << value << '\n'; 
     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 
    grand.join(); 
} 

void testClass::parent() 
{ 
    std::cout << "Starting child thread.\n"; 
    std::thread child(&testClass::child, this); 
    child.join(); 
} 
int main() 
{ 
    std::cout << "Starting program\n"; 
    std::cout << "Starting parent thread.\n"; 
    testClass parentclass; 
    parentclass.parent(); 
} 

出力:

Starting program 
Starting parent thread. 
Starting child thread. 
Starting grandchild thread. 
0  0 
1  0 
2  0 
3  5 
4  5 

live demo

+0

私は理解し始めていると思います。もし私が正しいなら結合の意味コンストラクタはすでにスレッドを起動し、それを待つだけです。私は正しい? – anon

+0

この例では、yesです。 'std :: thread'が構築され、開始されます(空のスレッドを構築するのとは対照的に)。そして、はい、 'join()'はそれが完了するのを待ちます。 – wally

+0

この例では、std :: threadが構築時に起動しない例があります_ – anon

関連する問題