2017-12-22 21 views
-1

Boost-Threadを使用するC++ 98プロジェクトがあります。メインスレッドは、このような12スレッド作成:スレッドとシグナル

for(int i=0;i<numCPU;++i) 
{ 
    vThreads.push_back(new boost::thread(boost::bind(&TControl::startCPU,this,i,fnp))); 
} 

およびワーカースレッドは、(限りgetWorkとして実行)ワークユニットを返す:

void startCPU(int id,StartFn fnp) 
{ 
    unused(id); 
    while(true) 
    { 
     WU_TYPE* pWU(getWork()); 
     if(pWU==NULL) return; 
     CALL_MEMBER_FN(pWU,fnp)(); 
    } 
} 

特定のワークユニットは、非常に長い実行してもよいです。目標は、スレッド(startCPU(void)を実行するスレッド)が新しいワークユニットを開始できるように、すでに60分以上のランタイムを持つワークユニットを強制終了することです。

これはシグナルによって実行できると主に考えました。つまり、メインスレッドが毎分シグナルを上げ、各スレッド内のシグナルハンドラが期限切れのワークユニットの例外をスローする可能性があります。しかし、少し読んだ後では、あるスレッドから生成されたシグナルが別のスレッドのシグナルハンドラを起動しないため、このように動作するようには見えません。この目標を達成するための適切な技術は何ですか?

注:C++ 11は使用できません。ソフトウェアは古いシステムでコンパイルする必要があります。

+0

前の開始時刻を覚えておいてください。 - >現在の時刻を確認してください。 - >終了時刻になると終了します。 - >この変数は、このスレッドが終了した作業単位を示します。 – Detonar

+0

CALL_MEMBER_FNは、ワークユニットpWUのメンバ関数ポインタfnpを実行し、ワークユニットが完了するまで戻りません。目標は毎分fnp()を中断し、それが殺されるかどうかを確認することです。 – Geom

答えて

0

現在スレッドで実行されているコードからのサポートがなければ、実行できません。スレッドはプロセスコンテキストを共有します。彼らはロックを取得してコンテキストを破損し、ロックを解除する前にコンテキストを元の状態に戻す必要があります。そうしないと、プロセスコンテキストが破損します。だから、現在実行しているコードの協力なしにスレッドを殺すことはできません。

協力してサポートしている方法を使用できます。コードがBoostのinterrupt機能をサポートしているなら、それを使うことができます。コードに割り込みポイントが実装されている必要があります。割り込みポイントが中断されているかどうかを確認してスレッドを正常終了させる必要があります。そうでなければinterruptは何もしません。他のメカニズムをサポートしている場合は、それを使用してください。しかし、それは最初から設計されなければならない。

それ以外の場合は、スレッドではなくプロセスでコードを分離します。奇妙なことをしない限り(メモリを共有するなど)、プロセスを終了することができます。

+0

ありがとうございます。しかし、スレッドはkillされません。void startCPU()を実行するスレッドは12個だけ起動します。 startCPU()では、多くの作業ユニットが繰り返し実行され、大規模な作業ユニットを殺したいだけです。私はアルゴリズムから頻繁に更新されるプログレスバーオブジェクトを既に持っており、そこで例外をスローすることができます。しかし、これは良い解決策ではありません。プログレスバーが更新されていないループでアルゴリズムが予期せず時間がかかるからです。だから私は信号経由での割り込みがより良い解決策になると思った。 – Geom

+0

@Geomそれはほとんど間違いない。しかし、すべてのコード信号を安全にしたい場合、それは機能します。 –

関連する問題