2017-08-28 7 views
2

シナリオ:スレッドがdllから作成された場合、std :: asyncはプロセス終了をブロックしていますか?

私は私が別のDLLからエクスポートされた関数(exported_func)を使用するコンソールアプリケーション(consoleApp)を有します。その関数では、私は新しい無限のスレッドを開始しました。

EXPERIMENTAL_API int exported_func(void) 
{ 
    auto f = []() { 
     while (true) 
     { 
      cout << "H"; 
      this_thread::sleep_for(100ms); 
     } 
     return 1; 
    }; 

    async_res.value = async(launch::async, f); 
    return 1; 
} 

、私はこの関数を呼び出した、その後私は、main関数で無限ループを開始しmain()機能から - ここでは、コードです。ここでは、コードです -

int main() 
{ 
    exported_func(); 

    while (true) 
    { 
     cout << "L"; 
     this_thread::sleep_for(100ms); 
    } 

    return 0; 
} 

問題:

問題は、私は、コンソールの[閉じる]ボタンをクリックして、私のコンソールアプリケーションを終了したい場合、それはアプリケーションを閉じるために10秒かかり、ということです。

さらに、私がCreateChildProcessを使ってプロセス(consoleApp.exe用)を作成した場合、そのプロセスはExitProcessを使用して終了できません。

しかし、(consoleAppの)main関数からスレッド(async)を作成するとすぐに終了し、ExitProcessを使って終了することができます。

ここで何が起きているのか説明できますか?

注:私はVisual Studio 17、したがってVisual C++ v141ビルドツールを使用しています。

+0

「async_res.value」とは何ですか? –

+0

'async_res'は構造体であり、' future value'はそのメンバーです。 –

+0

グローバル変数? –

答えて

1

閉じるボタンをクリックしてExitProcessを呼び出すと、ExitProcessが呼び出されます。

ExitProcessの部分は、ロードされた各DLLのDLLエントリポイント関数をDLL_PROCESS_DETACHと呼びます。

DLL_PROCESS_DETACHを受信したときにVC++ランタイムのDLLエントリポイント(_DllMainCRTStartup)がDLLのグローバル変数のデストラクタを呼び出すときの動作の一部。

共有状態が準備完了になるまでstd::asyncブロックによって返さstd::futureのデストラクタ - 1)あなたの関数が戻らないと、2)ExitProcessが強制的にとにかく機能を実行中のスレッドを終了しているため、それは、ないことはありません。

EXE are handled differentlyのグローバルオブジェクトで、少なくとも最新バージョンのランタイムライブラリでは、ExitProcessが呼び出されたときにデストラクタが呼び出されません。

+0

ありがとう!これはそのほとんどを説明しています。しかし、私はコンソールのクローズボタンを使って閉じると10秒後になぜそれが終了するのかよく分かりません。それはハングアップする必要がありますよね? –

+0

@RasheduzzamanSourov閉じるボタンはOSにプログラムに 'CTRL_CLOSE_EVENT'を送ります。そのためのデフォルトのハンドラは 'ExitProcess'を呼び出します。ハンドラの実行を許可する時間に制限があります。ハンドラがタイムアウトすると、Windowsは強制的にプロセスを強制終了します。 –

関連する問題