1.pthread_create()初体験


まずプログラムを見てみましょう
#include 
#include 
#include 
void *sayhello(void *arg)
{
    printf("hello, world! I'm son
"); } int main(void) { pthread_t son; pthread_create(&son, NULL, sayhello, NULL); printf("hello, world! I'm father
"); return 0; }
pthread_についてcreate()関数の紹介、ここで省略します!
マルチスレッドプログラムのコンパイルについて
いくつか注意すべき点があります.
1.ヘッダファイルはpthreadを参照する必要があります.hファイル、このファイルは私もどこにあるか分かりません.linuxカーネルのソースコードには見つかりません.コンパイラの中にあるかもしれません.
2.コンパイル時にpthreadライブラリをリンクする必要があります.たとえば、次のようにします.
“gcc -o main main.c -lpthread”
3.スレッドに対応する関数のフォーマットは、void*xxoo(void*arg)でなければなりません.
a.「void*sayhello(void*arg)」を「void sayhello(void*arg)」に変更すると、次のようにエラーが発生します.
root@book-desktop:/opt/pc_test/multithreading/1# make
gcc -o main main.c -lpthread
main.c: In function ‘main’:
main.c:14: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘void (*)(void *)’
b.「void*sayhello(void*arg)」を「void*sayhello(void)」に変更すると、次のようにエラーが発生します.
root@book-desktop:/opt/pc_test/multithreading/1# make
gcc -o main main.c -lpthread
main.c: In function ‘main’:
main.c:14: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(void)’
次にプログラムを実行します.結果は次のとおりです.
root@book-desktop:/opt/pc_test/multithreading/1# ./main 
hello, world! I'm father
ナニー!「ハロー、world!I'm son」はどうして現れなかったの?これは何が原因ですか?
プロセスの終了は、メイン関数main()で行うことができます.でexit、returnを直接呼び出すか、プロセス内の他のスレッドでexitを呼び出すことで実現します.いずれの場合も、プロセスのすべてのスレッドが終了します.プライマリ・スレッドが他のスレッドを作成した後に機能しない場合、またはプライマリ・スレッドが他のスレッドが終了するまで待つ必要がある場合、プライマリ・スレッドはすべてのスレッドが終了するまでブロックする必要があります.」
soga!以上の手順では、「hello,world!I'm father」を印刷するのが親スレッドのタスクであり、「hello,world!I'm son」を印刷するのは子スレッドがやるべきことであり、親スレッドは子スレッドを作成した後、親スレッドも子スレッドも内核で呼び出される機会があるが、何らかの理由で親スレッドが先に呼び出され、親スレッドの内容が少ないためか、瞬時に呼び出しが完了すると、サブスレッドがまだ来ていないか呼び出され、親スレッドが「return 0」という文に遭遇するため、プロセス全体が終了します.
どうやって破るの?つまり「printf("hello,world!I'm son");」と「printf("hello,world!I'm father");」いずれも実行できます.少なくとも次のような方法があります.
方法1:「return 0;」前に「sleep(1);」と付け加えた.
方法2:「親スレッド」に対応するプログラムに「pthread_join(son)」を付ける
方法3:「親スレッド」対応プログラムに「pthread_exit(NULL)」を付ける
方法1は、親スレッドに1秒の睡眠時間を与え、このとき、サブスレッドはカーネルに呼び出されるのに十分な時間と機会を有する.
方法2は、親スレッドが終了する前にサブスレッド(thread son)の実行を「待つ」ようにする.
方法3におけるpthread_exit()自体の役割は「呼び出しスレッドを終了するが、その前にサブスレッドがすべて実行されるのを待つ」のでpthread_exit(NULL)はmain関数のreturnの前に置かれ、その効果と「pthread_join(son 1,NULL);;pthread_join(son 2,NULL);pthread_join(son 3,NULL)...」差は多くない!
もっと多くのことはここでは言わないで、後で言います...