Linuxシステムプログラミング53スレッド-スレッドIDの取得、比較、スレッドの作成、終了、収集、スレッドスタックのクリーニング

pthread_equal()、スレッドIDを比較します

NAME
       pthread_equal - compare thread IDs 比较两个线程ID

SYNOPSIS
       #include <pthread.h>

       int pthread_equal(pthread_t t1, pthread_t t2);
// 不清楚 线程ID 类型,不能直接按照int类型数值的比较方法。

コンパイルして-pthreadでリンクします。

2つのスレッドIDが等しい場合、pthread_equal()はゼロ以外の値を返します。それ以外の場合は、0を返します。


pthread_self()、現在のスレッドのスレッドIDを取得します

NAME
       pthread_self - obtain ID of the calling thread

SYNOPSIS
       #include <pthread.h>

       pthread_t pthread_self(void);

       Compile and link with -pthread.

RETURN VALUE
       This function always succeeds, returning the calling thread's ID.

pthread_create()スレッドの作成

名前
pthread_create-新しいスレッドを作成します

書式
の#include <pthread.hの>

   int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);

   Compile and link with -pthread.

戻り値
での成功は、pthread_createの()は0を返します。エラーの場合、エラー番号を返し、* threadの内容は未定義です。

スレッドのスケジューリングは、スケジューラーのスケジューリング戦略に依存します

pthreadライブラリは標準のLinuxライブラリではないため、コンパイルはgcc thread.c-lpthreadに変更されます。

実験1

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void* func(void* p)
{
	puts("Thread is working!");
	return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	puts("End!");
	exit(0);

}

mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c  -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

スレッドのスケジューリングは、スケジューラの戦略によって異なります。作成したスレッドにスケジュールを設定する時間がなくなる前に、現在のプロセスはexit(0)で終了します。


pthread_exit()はスレッドを正常に終了します


スレッドを終了するには、次の3つの方法があります。1スレッドは起動ルーチンから戻り、戻り値はスレッドの終了コードです
。2スレッドは同じプロセス内の他のスレッドによってキャンセルできます
。3スレッドはpthread_exitを動員します。() 関数。

NAME
       pthread_exit - terminate calling thread  正常结束一个线程

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);

       Compile and link with -pthread.


RETURN VALUE
       This function does not return to the caller.

returnとは異なり、pthread_exit()を呼び出してスレッドを終了すると、スレッドスタックがクリーンアップされます。


pthread_join():スレッドコレクション

これは、プロセス段階でのwait()操作と同等です。関数は、スレッドの死体を収集し、スレッドの終わりが死体を収集するのを待つことです。

wait()とは異なり、死体を収集するターゲットを指定できます。wait()は誰がそれを受け取ったかしか知りません。

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

       int pthread_join(pthread_t thread, void **retval);
//thread 指定收尸的目标线程
       // void **retval  为空,表示 只收尸,不关心状态 

       Compile and link with -pthread.

戻り値
での成功は、pthread_joinを()は0を返します。エラーの場合、エラー番号を返します。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void* func(void* p)
{
	puts("Thread is working!");	
	pthread_exit(NULL);
	//return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	pthread_join(tid,NULL);//线程收尸,一直等待线程结束后收尸
	puts("End!");
	exit(0);

}



mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
Thread is working!
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

pthread_join()スレッド収集関数は、ターゲットスレッドが終了するのを待ってから死体を収集しているため、プロセスはtidスレッドのスケジューリングが終了するのを待ってからプロセスを終了することがわかります。死体収集アクションを実行した後、プロセスは終了(0)してプロセスを終了します。


スタッククリーニング
pthread_cleanup_push()
pthread_cleanup_pop()

思い出してください:フック関数atexit()、プロセスが正常に終了すると、この関数が呼び出され、フックにぶら下がっている関数が逆の順序で呼び出されます。ここでは、取り付けフックの関数を逆の順序で呼び出す操作です。 、介入できません。実行されます。

pthread_cleanup_push()関数は、フック関数をマウントするatexit()に似ていますが、pthread_cleanup_pop()は、フックにハングしている関数を削除するために使用されます。実行するかどうかは、パラメーターによって異なります。atexit()フック関数と比較して、ここでは自分で決めることができますマウントフックを実行する機能も逆の順序で実行されます。

名前
pthread_cleanup_push、pthread_cleanup_pop-プッシュおよびポップスレッドキャンセルクリーンアップハンドラー

SYNOPSIS
       #include <pthread.h>

// 将函数挂在钩子上。挂载的函数,挂载的函数的参数
       void pthread_cleanup_push(void (*routine)(void *),
                                 void *arg);

//决定当前从钩子上面取下来的函数是否被调用。  参数决定是否调用
       void pthread_cleanup_pop(int execute);

       Compile and link with -pthread.


pthread_cleanup_push()
pthread_cleanup_pop()に注意してください

これらの2つの関数はマクロであり、2つのマクロは組み合わせて使用​​されるため、ペアで表示する必要があります。そうしないと、文法エラーが発生します。

実験:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void cleanup_func(void* p)
{
	puts(p);
}

static void* func(void* p)
{
	puts("Thread is working!");	


	pthread_cleanup_push(cleanup_func,"cleanup1");
	pthread_cleanup_push(cleanup_func,"cleanup2");
	pthread_cleanup_push(cleanup_func,"cleanup3");

	puts("push over!");
	
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(1);
	
	pthread_exit(NULL);
	//return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	pthread_join(tid,NULL);
	puts("End!");
	exit(0);

}


mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
Thread is working!
push over!
cleanup3
cleanup2
cleanup1
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

pthread_cleanup_pop(0)の場合、実行されません。つまり、スタックのみがポップされ、対応する関数は実行されません。スタックをポップするだけで実行しない場合でも、書き込む必要があります。プッシュが複数ある場合は、それに対応するポップが複数ある必要があります。そうでない場合、文法上の問題が発生します。

おすすめ

転載: blog.csdn.net/LinuxArmbiggod/article/details/114226562