Linux System Programming 53 Threads-Thread ID acquisition, comparison, thread creation, termination, collection, thread stack cleaning

pthread_equal(), compare thread ID

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

SYNOPSIS
       #include <pthread.h>

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

Compile and link with -pthread.

If the two thread ids are equal, pthread_equal() returns a non-zero value; otherwise, it returns 0.


pthread_self(), get the thread ID of the current thread

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() thread creation

NAME
pthread_create - create a new thread

SYNOPSIS
#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.

RETURN VALUE
On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.

The scheduling of threads depends on the scheduling strategy of the scheduler

Since the pthread library is not a standard linux library, the compilation is changed to gcc thread.c -lpthread.

Experiment 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$ 

Thread scheduling depends on the scheduler strategy. Before the thread we created has time to schedule, the current process will end with exit(0).


pthread_exit() ends a thread normally

There are three ways to terminate a
thread : 1 The thread returns from the startup routine, and the return value is the exit code of the thread.
2 The thread can be cancelled by other threads in the same process.
3 The thread mobilizes the pthread_exit() function.

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.

Unlike return, calling pthread_exit() to terminate the thread will clean up the thread stack.


pthread_join(): thread collection

It is equivalent to the wait() operation in the process stage. The function is to collect the corpse of the thread, and wait for the end of the thread to collect the corpse.

Unlike wait(), you can specify the target to collect the corpse, wait() only knows who received it.

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.

RETURN VALUE
On success, pthread_join() returns 0; on error, it returns an error number.

#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$ 

It can be seen that the process is waiting for the tid thread scheduling to end before ending the process, because the pthread_join() thread collecting function has been waiting for the target thread to end and then collecting the corpse. The process will exit(0) to end the process after executing the corpse collection action.


Stack cleaning
pthread_cleanup_push()
pthread_cleanup_pop()

Review: the hook function atexit(), when the process terminates normally, the function will be called, and the function hanging on the hook will be called in reverse order. Here, the operation of calling the function on the mounting hook in reverse order, we cannot intervene. Will be executed.

The pthread_cleanup_push() function is similar to atexit(), which mounts the hook function, while pthread_cleanup_pop() is used to remove the function hung on the hook. Whether to execute it depends on the parameters. Compared with the atexit() hook function, here we can decide by ourselves The function of which mount hook is executed is also executed in reverse order.

NAME
pthread_cleanup_push, pthread_cleanup_pop - push and pop thread cancellation clean-up handlers

SYNOPSIS
       #include <pthread.h>

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

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

       Compile and link with -pthread.

Note that
pthread_cleanup_push()
pthread_cleanup_pop()

These two functions are macros, and the two macros are used in combination and must appear in pairs, otherwise there will be grammatical errors.

experiment:

#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$ 

If it is pthread_cleanup_pop(0); it will not be executed, that is, only the stack will be popped and the corresponding function will not be executed. Even if it only pops the stack and does not execute it, it must be written. If there are several pushes, there must be several corresponding pops, otherwise there will be grammatical problems.

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/114226562