Linux- thread termination

Termination of the thread

Linux There are two ways you can make a normal thread termination:

  • By returnreturning from the thread function
  • By calling the pthread_exit()function, the thread exits

In addition to interference from other threads or threads of their own mistakes, it can lead to abnormal thread termination, and such termination is unpredictable.
Whether the thread is normal termination or abnormal termination, it will involve a resource release problem:

  • In the case of normal termination of the thread, the thread can automatically release resources
  • In the case of abnormal termination of the thread, calling pthread_cleanup_push()\pthread_cleanup_pop()both a function to cleanup thread

Use return to return to the thread

returnWe are very familiar with the C language in the learning process, especially in the essential primary function, and finally add return 0, at the time a function is called, as long as the execution return, the called function will return to the main function in.
So, returnwith a return to the calling function to the main function of the function, use the function in the calling thread returnwill cause the thread exits, exit to the process.
However, if mainthe calling function return, the entire process will exit, threads in the process also will be terminated.

Call pthread_exit () to terminate the thread

pthread_exit()Make the thread function is terminated normally, the use of thread, a thread of execution when to pthread_exit()when this step will normally terminated, and returns a data (pointer).
Prototype:

void pthread_exit( void *value_ptr );
  • value_ptr is a pointer, it can be stored return value of a thread, and can be pthread_join()a function of receiving the second parameter.

Cleanup thread resources when abnormal termination

When a thread abnormal termination, the thread with the resources will not be automatically released, so we have to call clear function, to clean up the thread resources. That is, the cleanup thread cleanup function is to rely on resources to complete this cleanup function written by the user. Then the program knows how to terminate the thread is normal or abnormal termination of it? A thread is a function of how the calling thread to clean it?

Linux system provides a pair of functions, is used to detect abnormal termination of the thread and the calling thread cleanup function, their function prototype is as follows:

void pthread_cleanup_push( void( *routine )( void* ), void *arg );
void pthread_cleanup_pop( int execute );
  • void( *routine )( void* )It is the thread cleanup function
  • void *argIt is to pass parameters thread cleanup function
  • int executeThere are two kinds of values: 0 and non-0

When in use, pthread_cleanup_push()and pthread_cleanup_pop()are likely to cause problems in your code the beginning and end, so that you can monitor this piece of code, and if there is an abnormal termination in this section of code, or call pthread_exit()termination, will trigger cleanup function, we just need to thread cleanup operation can be written in the thread cleanup function.
Another point, if pthread_cleanup_pop()the parameter is 0, even if the code does not trigger a cleanup function, will perform a final cleanup function. This is the parameter int executeeffect when not 0, if there is no trigger cleanup function, no longer perform cleanup function.

The execution order when setting up multi-thread cleanup function
as well, when set on the same piece of code multiple cleanupfunctions, the order of execution of each thread cleanup function is a last-out type of execution, that is, the thread cleanup function layers from the innermost begin . This pthread_cleanup_push()function-related, push means pressing, pushing, thread cleanup function This function will be called onto the stack, and the data stack are last-out, it also explains the multi-thread cleanup function the execution order.

Routine

The following piece of code to analyze the event of termination of the thread

#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;
}

Results are as follows:
Here Insert Picture Description
It can be seen that:

  • First: when the thread 1 is returned without triggering cleanup function, explain the situation does not trigger a return to return to the thread cleanup function
  • Second: cleanup function execution order of the thread 2 is from the innermost begin, in line with the characteristics of the stack
  • Third: pthread_exit()returns a termination function exit codevalues, may be pthread_join()read in this blocking function value is transmitted to the address of a pointer variable, and then print out
Published 62 original articles · won praise 188 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43743762/article/details/101056692