割り当てられたメモリが所有されていることを確認してください
割り当てられたすべてのメモリが、C ++ 03のauto_ptr、C ++ 11のunique_ptr、Boostのscoped_ptr、またはshared_ptr(共有、コピー、移動が可能)のいずれかのスマートポインタによって所有されていることを確認してください。
このようにして、RAIIはメモリリークからユーザーを保護します。
スレッドを中断するためのさまざまな方法を説明しているハーブサッターの記事、InterruptPolitelyを読んでください。
今日、 Boost.Thread 1.37を使用すると、例外をスローしてスレッドを終了するように要求できます。Boostでは、これはboost :: thread_interrupted例外であり、任意の割り込みポイントから例外をスローします。
したがって、ある種のメッセージループを処理したり、グローバル/共有データを検証したりする必要はありません。メインスレッドはワーカースレッドに例外を介して停止するように要求し、ワーカースレッドが割り込みポイントに到達するとすぐに例外がスローされます。前述のRAIIメカニズムにより、割り当てられたすべてのデータが正しく解放されます。
スレッドで呼び出される疑似コードがあるとしましょう。これは、おそらくメモリを割り当てる関数のようなものであり、ループ内で多くの計算を行う関数のようなものである可能性があります。
Object * allocateSomeObject()
{
Object * o = NULL ;
if(/*something*/)
{
// Etc.
o = new Object() ;
// Etc.
}
return o ; // o can be NULL
}
void doSomethingLengthy()
{
for(int i = 0; i < 1000; ++i)
{
// Etc.
for(int j = 0; j < 1000; ++j)
{
// Etc.
// transfert of ownership
Object * o = allocateSomeObject() ;
// Etc.
delete o ;
}
// Etc.
}
}
上記のコードは安全ではなく、メモリがC ++オブジェクト(通常はスマートポインタ)によって所有されることを常に確認するための手順が実行されない場合、割り込みモードに関係なくリークします。
このように変更して、コードを割り込み可能にし、メモリセーフにすることができます。
boost::shared_ptr<Object> allocateSomeObject()
{
boost::shared_ptr<Object> o ;
if(/*something*/)
{
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
o = new Object() ;
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
return o ; // o can be "NULL"
}
void doSomethingLengthy()
{
for(int i = 0; i < 1000; ++i)
{
// Etc.
for(int j = 0; j < 1000; ++j)
{
// Etc.
// transfert of ownership
boost::shared_ptr<Object> o = allocateSomeObject() ;
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
// Etc.
boost::this_thread::interruption_point() ;
// Etc.
}
}
void mainThread(boost::thread & worker_thread)
{
// etc.
if(/* some condition */)
{
worker_thread.interrupt() ;
}
}
Boostを使用しませんか?
Boostを使用しない場合は、これをシミュレートできます。スレッドを中断する必要がある場合は、スレッドストレージのブール値のような変数を「true」に設定します。この変数をチェックする関数を追加し、trueの場合は特定の例外をスローします。スレッドの「ルート」にこの例外をキャッチさせて、正しく終了させます。
免責事項
現在、Boost 1.37にアクセスできないため、前のコードをテストすることはできませんが、アイデアはあります。私はこれをできるだけ早くテストし、最終的にはより完全な/正しい/コンパイル可能なコードを投稿します。