Article Directory
Termination of the thread
Linux There are two ways you can make a normal thread termination:
- By
return
returning 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
return
We 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, return
with a return to the calling function to the main function of the function, use the function in the calling thread return
will cause the thread exits, exit to the process.
However, if main
the 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 functionvoid *arg
It is to pass parameters thread cleanup functionint execute
There 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 execute
effect 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 cleanup
functions, 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:
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 functionexit code
values, may bepthread_join()
read in this blocking function value is transmitted to the address of a pointer variable, and then print out