linux pthreadステータスとpthread終了


主に2つの問題を説明したい:スレッドの2つのタイプ(状態):joinとdetach、そしてスレッド関数のpthread_exitとreturnの違い1.joinとdetach.join:スレッドA作成スレッドB(C,D.....)その後、AがスレッドBの結果を待つ必要がある、あるいはABが同期する必要がある.あるいはAはBの結果を待つ必要がある.このときjoin状態スレッドを作成する場合、デフォルトはjoin状態です.同じプロセスの下のスレッドはpeerであり、他のスレッドがjoin Bを待つことができ、A.joinだけがリソースを解放するわけではない.detach:スレッドAはスレッドBを作成した後、Aにとって、よし、私の任務は終わった、Bは自分で遊びに行きましょう.AはBの結果を待つ必要がない、あるいはBの終了を待つ必要がない場合である.このときdetach状態である.joinと比較して、スレッドの実行が完了すると、自動的にリソースが解放されます.この2つの状態の選択は実際には需要上の設計を見る.例えば、linuxのネイティブ情報、cpu、mem、disk、netを自分で取得する場合、4スレッドを開いて情報を収集する必要があり、すべて収集が完了するまで待ってからまとめる.4つのスレッドの戻りを待つ必要がある.デザインはjoin.int pthread_join(pthread_t thread,void**rval_ptr)//2次ポインタ(ちなみにAPUE第2版294ページ上コードerr=pthread_join(tid 1,(void*)&fp);//voidここではマニュアルとAPUEの説明を見てみましょう.1.特定のスレッドの戻りを待ち、スレッドがまだ実行中である場合、待ちをブロックし、実行が完了した場合、直ちに2を返す.返されたポインタがコピーするターゲットスレッドの終了時のポインタ(一級ポインタ)の値.ターゲットスレッドがキャンセルされた場合、PTHREAD_に戻ります.CANCELED. 戻り値はreturn(void*)ptrまたはpthread_exit((void*)ptr)はスレッドから返す.joinが受信する3.複数のスレッドが同時に1つのスレッドをjoinする場合、結果は定義されない.エラーが発生する可能性があります.異なるスレッドでjoin同じスレッドを複数回呼び出さないでください.4.pthread_の場合joinはキャンセルされ、スレッドは依然としてjoin状態である.5.join可能なスレッドについては、スレッドが戻った後にリソースを解放するのではなく、joinを待ってから解放されるリソースである.6.joinの前にjoinしたスレッドは定義されていません.異常がある可能性がある.1つのプロセスのすべてのスレッドはpeerであり、任意のスレッドはjoinして他のスレッドに行くことができる.8.joinスレッドが失敗するとゾンビスレッドが発生する.9.スレッドにプロセス関数waitpid(-1,&status,0)/-1のようなプロセスはない.任意のスレッドの関数を受信できます.すなわち、pthread_を指定する必要があります.t 10.分離状態のスレッドであるdetach状態に対してはエラーを返す.スレッドがdetach状態になるには2つの方法がある:1.関数:int pthread_detach(pthead_t tid); 2.スレッド属性の設定.スレッドが作成されるとcreate関数に属性変数があります.pthread_attr_setdetachstate(&attr,PTHREAD_DETACHED); 分離状態のスレッドは、実行後、自動的にリソースを解放するだけである.プロセス(プライマリスレッド)returnまたはexitの場合、分離状態のスレッドは依然として終了する.pthread_joinとpthread_detachは、スレッド関数を作成するスレッドで呼び出されてこそ、リソースを解放する.マニュアルに面白い例を示した.
pthread_detach(pthread_self());検証対象
最後にマニュアルでpthread_detach上:
pthread_joinとpthread_detachは、スレッドを作成するスレッドによって呼び出されるべきであり、もちろん、すべてのスレッドが終了すると、すべてのリソースが解放される.
2.returnとpthread_exit
returnとpthread_exitの違い:「理論的には、pthread_exit()とスレッドシンク関数が終了する機能は同じであり、関数の終了時に内部でpthread_exit()が自動的に呼び出されてスレッド関連のリソースがクリーンアップされる.しかし、実際には両者はコンパイラの処理によって大きく異なる.プロセスマスター関数(main()でpthread_exit()が呼び出され、マスター関数が存在するスレッドのみが使用される(プロセスのメインスレッドと言える)終了;一方、returnの場合、コンパイラは、_exit()などのプロセスが終了したコードを呼び出し、プロセスとそのすべてのスレッドが実行を終了します.」
だから、宿体関数内には違いはありません(理論的に).ただし、ホスト関数ではreturnがプロセスを終了します.
pthread_exit()はスレッドの終了に使用され、他のスレッドがpthread_を通過するように戻り値を指定できます.join()関数は、スレッドの戻り値を取得します.
returnは、関数が返すので、スレッド関数とは限らないよ!スレッド関数returnのみがスレッドを終了します
exit()はプロセスの終了であり、スレッド関数でexitを呼び出すと、スレッドを変更するプロセスも停止し、そのスレッドが存在するプロセスの他のスレッドも停止する.
スレッド(プライマリスレッド以外)ではreturnが呼び出されるとpthread_が暗黙的に呼び出されますexit.
両者の具体的な違いを調べてみました:大体の意味は:
pthrad_exitはメモリの漏洩、dopenライブラリファイルを引き起こす可能性がありますが、dcloseはありません.他の使用が可能であるためです.
returnを使用するとこのような状況は発生しない.使用する検出ソフトはvalgrind.
自分でテストして、今pthread_exitはメモリ漏洩の可能性はない.検索した情報は少し古くなった.
テスト環境:valgrind-3.7.0カーネル:3.5.0-23-generic
cとc++の2種類をテストする.結局メモリが漏れなかった.
コード:
C
#include 
#include 
#include 
#include 
#include 

void *app1(void *x) 
{
    printf("in thread
"); pthread_exit(0); } int main() { pthread_t t1; pthread_create(&t1, NULL, app1, NULL); pthread_join(t1, NULL); return 0; }

c++コードもあまり差がない.
もう1つの例:これは伝達する主関数スタックのポインタ(アドレス)である.
#include 
#include 

using namespace std;

struct taskdata
{
       int  x;
     float  y;
    string  z;
};


void* task1(void *data)
{
    taskdata *t = (taskdata *) data;

    t->x += 25;
    t->y -= 4.5;
    t->z = "Goodbye";

    return(data);
}

void* task2(void *data)
{
    taskdata *t = (taskdata *) data;

    t->x -= 25;
    t->y += 4.5;
    t->z = "World";

    pthread_exit(data);
}


int main(int argc, char *argv[])
{
    pthread_t threadID;

    taskdata t = {10, 10.0, "Hello"};

    void *status;

    cout << "before " << t.x << " " << t.y << " " << t.z << endl;

    //by return()

    pthread_create(&threadID, NULL, task1, (void *) &t);

    pthread_join(threadID, &status);

    taskdata *ts = (taskdata *) status;

    cout << "after task1 " << ts->x << " " << ts->y << " " << ts->z << endl;

    //by pthread_exit()

    pthread_create(&threadID, NULL, task2, (void *) &t);

    pthread_join(threadID, &status);

    ts = (taskdata *) status;

    cout << "after task2 " << ts->x << " " << ts->y << " " << ts->z << endl;

}

関数が終了すると、スタックの内容が解放され、return/pthread_exit、どのように伝達するパラメータですか.ネット上ではreturnとpthread_exitパラメータをpthread_に置くジョンの場所
pthread_exitとreturnのもう一つの違いは:
スレッドが起動ルーチンから戻る終了である場合、スレッドクリーンアップハンドラは呼び出されない.APUE书上(未検証)
最后に自分で文をまとめます:普通はやはりreturnを使って、もしスレッドの処理プログラムがあるならば、更に総合的に考えます.ネット上では、できるだけスレッドreturnなどを使用しないで、Boost thread libraryなどを使用して、パッケージされたライブラリを使用して、より多くの問題を避けることをお勧めします.
参照:
http://hwood.blog.163.com/blog/static/87581175201152354550727/
http://blog.csdn.net/zuifeng503/article/details/8463818
http://stackoverflow.com/questions/8751017/pthread-why-people-bother-using-pthread-exit
http://stackoverflow.com/questions/3692591/return-versus-pthread-exit-in-pthread-start-functions