web-dev-qa-db-ja.com

C ++で切り離されたスレッドを終了または停止するにはどうすればよいですか?

分離されたスレッドをC++で終了/停止/強制終了することに興味があります。これはどのように行うことができますか?

void myThread()
{
    int loop = 0;
    while(true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        ++loop;
    }
}

void testThread()
{
    std::thread globalThread(myThread);
    globalThread.detach();
}

int main(void)
{
    testThread();
    for(unsigned int i=0; i < 1000; i++)
    {
        cout << "i = " << i << endl;
    }
    return 0;
}

GlobalThread()を「停止」/「終了」したいのは、valgrindがこれが「失われた可能性のある」タイプのメモリリーク(152バイト)であることを示しているためです。これに対処する最良の方法は何ですか?

14
codeshark

別のスレッドを停止するための規定はありません。分離されているか、結合可能か。

スレッドを停止する唯一の方法は、スレッドが初期スレッド関数から戻ることです。

この特定のケースでは、次の変更を提案します。

  1. 糸を外さないでください。 main()でインスタンス化します。
  2. Bool値とstd::mutexを追加すると、boolはfalseに初期化されます
  3. スレッドの内部ループを通過するたびに、std::unique_lockを使用してミューテックスをロックし、ブール値を取得して、ミューテックスをロック解除します。ミューテックスのロックを解除した後、ブール値がtrueの場合は、ループを抜けて戻ります。
  4. Main()で、終了する前に:ミューテックスをロックし、ブールフラグをtrueに設定し、ミューテックスをロック解除してから、スレッドに参加します

2番目のスレッドがブールフラグをチェックして戻るまでに最大5秒かかるため、これは完璧ではありません。しかし、これが最初のtepになります。

12
Sam Varshavchik

C++標準を下回り、OS固有の関数を使用することができます。たとえば、独自のプロセスにシグナルマスクを設定しながらシグナルを送信し、分離されたスレッドにのみ配信されるようにします。ハンドラーは、スレッドからポーリングされるフラグを設定できます。メインルーチンがポーリング期間プラスビットよりも長く待機している場合は、終了したはずです;-P。同じ一般的な考え方は、アトミックのterminate-asapフラグ変数などの他のシグナリングメカニズムでも使用できます。

または、最後の手段としてのみ _pthread_cancel_ と同様のものがあります。このような非同期キャンセルは、一般的に危険なことであることに注意してください。終了するスレッドは、リソースがロック/取得されているコードに含まれていないか、デッドロック、リーク、および/または未定義の動作が発生する可能性があることに注意してください。 。たとえば、コードがstd::this_thread::sleep_for(std::chrono::seconds(5));を呼び出します-インターバルが終了したときにコールバックをOSに要求した場合、その後継続する関数は終了したスレッドのスタックを使用しますか?安全な例として、スレッドがアプリ内のループで単純な数値処理を行っている場合が挙げられます。

それ以外の場合、最初にスレッドを切り離さないようにすると、Samの回答に代替案が記載されます。

2
Tony Delroy

切り離されたスレッドを完全にシャットダウンする方法はありません。これを行うには、クリーンアップが完了するのを待つ必要があります。これは、スレッドが参加可能である場合にのみ実行できます。

たとえば、スレッドが、正常にシャットダウンするために別のスレッドが取得する必要があるミューテックスを保持している場合を考えます。そのスレッドを完全にシャットダウンする唯一の方法は、そのミューテックスを解放するようにスレッドを誘導することです。それにはスレッドの協力が必要です。

スレッドがファイルを開き、そのファイルのロックを保持しているかどうかを検討してください。スレッドを中止すると、プロセスが完了するまでファイルはロックされたままになります。

スレッドが共有状態を保護するミューテックスを保持していて、その共有状態を一時的に不整合な状態にしたかどうかを検討してください。スレッドを終了すると、ミューテックスが解放されないか、保護されたデータが矛盾した状態でミューテックスが解放されます。これにより、クラッシュが発生する可能性があります。

正常にシャットダウンするには、スレッドの協力が必要です。

2
David Schwartz