2016-06-20 8 views
0

私はC++ファイルのソースであるTCLファイルを持っています。 私は最後にすべてのTCL呼び出しを処理するためにTcl_DoOneEvent関数を使用しています。 また、Main関数で呼び出されるスレッドがいくつかあります。すべてのスレッドと関数を終了するために、私はquit関数を書いています。したがって、現在のケースでは、すべてのpthreadおよびその他の関数は、最後に呼び出されるTcl_DoOneEvent関数を除いて終了しています。セグメンテーションエラーが発生しています。 はwhile(1)関数を他の関数から抜け出す方法です。 whileループを終了するためにTcl_DoOneEvent関数を終了する

main() 
{ 
... 
... 
pthread_create(thread1); 
pthread_create(thread2); 
while(1) Tcl_DoOneEvent(TCL_ALL_EVENTS); 
return(0); 
} 

quit_fn() 
{ 
... 
... 
pthread_cancel(thread1); 
pthread_cancel(thread2); 
... 
// exit(0) ; -> this also results in segmentation error 
} 

答えて

1

、あなたは、ループの状態を変更すると、それはあなたが別のスレッド(揮発性として宣言)から変更することができます変数に依存するべきです。

volatile bool exitLoop = false; 

while (!exitLoop) 
{ 
    Tcl_DoOneEvent(TCL_ALL_EVENTS); 
} 

私はわかりませんが、それ以上のイベントがなければ、これは無期限にブロックされる可能性があります。 Tcl_DoOneEventが目を覚ますように

Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); 
// sleep some time here in order to avoid busy wait 

またはそれ以上は、あなたの終了関数からのイベントをトリガし、次の反復であなたのexitLoop変数が真である:2つの解決策は、TCL_DONT_WAITフラグを使用している場合があります。

最後に、すべてのスレッドに対して同じループと終了条件のアプローチを実行することをお勧めします。スレッドを終了するためにpthread_cancelを使用する代わりに、pthread_joinを使用してみてください。そうすることで、スレッドが終了する時点を正確に制御し、クリーンアップを実行し、セグメンテーションフォルトやその他の種類のエラーを回避することができます。

+0

quit機能を使用すると、メインスレッドにイベントを送信することをお勧めします。イベントは簡単なハンドラを持つことができます。あるいは、イベントハンドラは 'exitLoop'をセットすることができます。これは、あるスレッドからのみアクセスされるため、' volatile'である必要はありません。このユースケースでは 'TCL_DONT_WAIT'は推奨されません。 Tclはイベントなしで効率的にスリープします。 –

+0

私はそれに同意し、イベントを送信して、Tclがスリープを処理できるようにします。フラグは他のスレッドから決して使用されない限り、volatileは必要ありません(ただし、コードの場合はわかりません)。 –

関連する問題