スレッドの終了
Linuxでは、あなたが通常のスレッドの終了を作ることができる2つの方法があります。
- よる
return
スレッド関数から戻ります - 呼び出すことで
pthread_exit()
機能を、スレッドが終了
自分の間違いの他のスレッド又はスレッドからの干渉に加えて、それは異常なスレッドの終了につながる可能性があり、そのような終了が予測不可能です。
スレッドが正常終了か異常終了であるかどうか、それが関与しますリソース解放問題を:
- スレッドの正常終了の場合は、スレッドは自動的にリソースを解放することができます
- スレッドの異常終了の場合には、呼び出し
pthread_cleanup_push()\pthread_cleanup_pop()
のクリーンアップスレッドへの機能の両方を
スレッドへの復帰への復帰の使用
return
我々は、特に不可欠な主要機能で、学習過程におけるC言語に精通している、そして最後に追加しreturn 0
、関数が呼び出された時点で、限り実行などreturn
、呼び出された関数は、main関数に戻ります。インチ
だから、return
機能の主な機能を呼び出す関数への復帰と、呼び出し元のスレッドで関数を使用するreturn
プロセスにスレッドが終了、終了の原因となります。
ただし、main
関数呼び出しはreturn
、全体のプロセスが終了する、プロセス内のスレッドも終了します。
スレッドを終了する)(pthread_exitを呼び出し
pthread_exit()
作るスレッド関数は、通常、スレッドの使用を終了し、実行のスレッドの場合にpthread_exit()
、このステップが正常に終了する時期、および戻りデータ(ポインタ)。
プロトタイプ:
void pthread_exit( void *value_ptr );
- value_ptrは、スレッドの戻り値を格納することができ、そしてすることができ、ポインタである
pthread_join()
第二のパラメータを受信する機能。
クリーンアップスレッドリソース異常終了
スレッド異常終了は、リソースを持つスレッドが自動的に解放されることはありません場合は、私たちは、スレッドのリソースをクリーンアップするために、明確な関数を呼び出す必要があります。つまり、クリーンアップスレッドのクリーンアップ機能は、完了するためのリソースに依存することである利用者によって書かれたこのクリーンアップ関数を。そして、プログラムは、それが正常か異常終了のですか?スレッドを終了する方法を知っていますか スレッドは、呼び出し元のスレッドがそれをきれいにする方法の関数でありますか?
Linuxシステムは、機能の組を提供するスレッドと呼び出したスレッドクリーンアップ機能の異常終了を検出するために使用される次のように、それらの機能のプロトタイプは以下のとおりです。
void pthread_cleanup_push( void( *routine )( void* ), void *arg );
void pthread_cleanup_pop( int execute );
void( *routine )( void* )
これは、スレッドのクリーンアップ機能でありますvoid *arg
これは、パラメータにスレッドクリーンアップ関数を渡すことですint execute
0と非0:値の2種類があります
使用中に、ときpthread_cleanup_push()
やpthread_cleanup_pop()
、あなたのコード最初と最後で問題を引き起こす可能性があるので、あなたは、コードのこの部分を監視することができ、およびコード、またはコールのこのセクション内の異常終了がある場合pthread_exit()
、終了は、クリーンアップ機能をトリガする、私達はちょうどに必要スレッドのクリーンアップ操作は、スレッドのクリーンアップ機能で書き込むことができます。
もう一つのポイントは、場合pthread_cleanup_pop()
パラメータコードがクリーンアップ機能をトリガしない場合であっても、0であり、最終的なクリーンアップ機能を実行します。これは、パラメータであるint execute
何のトリガのクリーンアップ機能がない場合は0でないが、もはやクリーンアップ機能を実行する効果。
マルチスレッドクリーンアップ機能を設定実行順序
コード複数の同じ部分に設定した場合、同様にcleanup
最も内側からスレッドクリーンアップ機能層が始まる、ある機能は、各スレッドのクリーンアップ関数の実行順序は、実行の最後のアウト型であり、 。このpthread_cleanup_push()
機能に関連し、プッシュ手段が、それはまた、マルチスレッドのクリーンアップ機能を説明し、この関数はスタックに呼び出され、データスタックは、最後に出ている、プッシュ、スレッドのクリーンアップ機能を押します実行順序。
ルーチン
次のコードは、スレッドの終了のイベントを分析します
#include "stdio.h"
#include "pthread.h"
#include "unistd.h"
/* 线程清理函数,这里的清理函数没有清理线程的功能,就是为了分析一下函数的执行 */
void *clean( void *arg )
{
printf("cleanup:%s",arg);
return ( void* )0;
}
/* 线程1 */
void *thread1( void *arg )
{
printf("thread 1 start !\n");
pthread_cleanup_push( ( void* )clean, "thread 1 first handler \n" );
pthread_cleanup_push( ( void* )clean, "thread 1 second handler \n" );
printf("thread 1 push complete \n");
/* 线程1以return的方法返回 */
if( arg )
{
return ( void* )1;
}
pthread_cleanup_pop( 0 );
pthread_cleanup_pop( 0 );
return ( void* )1;
}
/* 线程2 */
void *thread2( void *arg )
{
printf("thread 2 start !");
pthread_cleanup_push( ( void* )clean, "thread 2 first handler \n" );
pthread_cleanup_push( ( void* )clean, "thread 2 second handler \n" );
printf("thread 1 push complete \n");
/* 线程2以调用pthread_exit()的方式终止 */
if( arg )
{
pthrea_exit( ( void* )2 );
}
pthread_cleanup_pop( 0 );
pthread_cleanup_pop( 0 );
pthread_exit( ( void* )2 );
}
int main( void )
{
pthread_t tid1,tid2;
int error;
/* 传递线程结束时返回的值 */
void *tret;
/* 创建线程1并传递参数 1 */
error = pthread_create( &tid1, NULL, ( void* )thread1, ( void* )1 );
if( error )
{
printf("thread 1 create failed \n");
return -1;
}
/* 创建线程2并传递参数1 */
error = pthread_create( &tid2, NULL, ( void* )thread2, ( void* )1 );
if( error )
{
printf("thread 2 create failed \n");
return -2;
}
/* 阻塞进程,执行线程1 */
error = pthread_join( tid1, &tret );
if( error )
{
printf("thread 1 join failed \n");
return -1;
}
printf("thread 1 exit code is %d\n",( int )tret);
/* 阻塞进程,执行线程2 */
error = pthread_join( tid2, &tret );
if( error )
{
printf("thread 2 join failed \n");
return -2;
}
printf("thread 2 exit code is %d\n",( int )tret);
return 1;
}
:結果は以下の通りである
:それはすることがわかります
- まず:スレッド1はクリーンアップ機能をトリガすることなく返されたときに、スレッドのクリーンアップ機能に戻るにはリターンをトリガしない状況を説明
- 第二:スレッド2のクリーンアップ関数の実行順序は、スタックの特性に合わせて、最も内側の開始からのものです
- 第三:
pthread_exit()
終了関数の戻りexit code
値を、することができるpthread_join()
。このブロッキング関数値で読み出しポインタ変数のアドレスに送信され、次いで印刷されます