2017-07-26 26 views
1

std :: threadの終了時にコールバック関数を実行する必要があり、メインスレッドでコールバック関数を実行する必要があります。std :: threadのメインスレッドでコールバック関数を実行する

スレッドの作成時にスレッドを切り離す必要があり、スレッドの完了のためにメインループの実行をブロックできません。

私がのstd ::信号を使用してみましたが、それがメインスレッド

#include <thread> 
#include <csignal> 
#include <iostream> 


std::thread::id main_thread_id; 

void func2() 
{ 
    for(int i = 0; i < 10000000; i++) 
    { 
     // do something 
    } 
} 

void func() 
{ 
    for(int i = 0; i < 10; i++) 
    { 
     func2(); 
    } 
    std::raise(SIGUSR1); 
} 

void callback(int signal) 
{ 
    std::cout << "SIGNAL: " << signal << "  THREAD ID:" << 
    std::this_thread::get_id() << std::endl; 
    bool b = std::this_thread::get_id() == main_thread_id; 
    std::cout << "IS EXECUTED ON MAIN THREAD: " << b << std::endl; 
} 

int main() 
{ 
    main_thread_id = std::this_thread::get_id(); 
    std::cout << "MAIN THREAD ID: " << std::this_thread::get_id() << std::endl; 
    std::signal(SIGUSR1, callback); 
    std::thread t1(func); 
    t1.detach(); 

    for(int i = 0; i < 20; i++) 
    { 
     func2(); 
    } 

    if(t1.joinable()) 
     t1.join(); 
} 

にコールバック関数を実行していないようだ私が得る結果はコールバック関数は、メインスレッド上で実行されていないということです。スレッドの終了時にワーカースレッドを作成し、メインスレッドでコールバック関数を呼び出す方法を提案してください。ヘルプ

+0

'std :: signal(SIGUSR1、callback);によって返される値を確認してください。一部の実装では、シグナルハンドラの設定を無効にすることができます。その場合、 'SIG_ERR'(-1)が返されます。 – ikleschenkov

+0

スレッド内のスレッド(メインまたは他のスレッド)をトラックで停止させ、何らかのコードを実行してから何も起こらないように再開することはできません。スレッドは、実行する作業をチェックする方法で記述し、それを実行する必要があります。たとえば、[プロデューサ - コンシューマ](https://www.cs.cornell.edu/courses/cs3110/2010fa/lectures/lec18.html)契約のコンシューマになる可能性があります。 –

答えて

4

ため

おかげでこれを行うには、いくつかの方法があります。

まず、メインスレッドはメッセージループを実行している可能性があります。この場合、メインスレッドにいくつかのコードを実行するように指示するペイロードを持つメッセージをキューに入れます(メインスレッドへのメッセージのポインタ部分を介して実行するコードを運ぶか、スレッドチェック)。

2番目の方法は、std::future<std::function<void()>>オブジェクトのようなものを返すことです。メインスレッドは、未来が準備できているかどうかを確認します。準備ができたら、コードを実行します。

第3の方法は、メインスレッドが待機する同時キューを作成し、メッセージ(実行するコードを含む)をそのキューに入れておくことです。

これらのすべてには、メインスレッドの積極的な協力が必要です。メインスレッドはプリエンプトできず、協力しないと別のコードを実行するように指示することはできません。

あなたの質問に言及しなかったプログラムの機能によって最適なものはどれですか。メッセージループを持つGUIの場合は、メッセージループを使用します。一部の仕事をパラレル化するストリーミングプロセッサーで、プロンプト実行を必要とせず、最終的には並列作業をブロックしたい場合は、将来がベストかもしれません。チャネルタイプのアプリを渡すメッセージの場合は、キューのセットが最適かもしれません。

関連する問題