目录
一、压栈、或弹栈线程的取消处理例程
1、原因
由于线程任何时刻都可能有互斥锁、信号量等资源,一旦被取消很有可能导致别的线程出现死锁,因此如果一条线程的确可能被取消,在取消之前应该用以下的API为可能出现的取消请求注册“处理例程”,让这些例程自动释放持有的资源。
2、相关API
3、代码
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
void test(void * arg )
{
printf("收到取消请求, 参数arg : %d \n" , *(int *)arg);
}
void * func (void * arg)
{
int * p = calloc(1,4);
*p = 1024 ;
// 压入取消处理函数
pthread_cleanup_push( test , p );
while(1)
{
printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
sleep(2);
break ;
}
//线程退出处理函数弹出, 0 不执行该函数 , 非0 则执行该处理函数
pthread_cleanup_pop( 0 );
// 退出本线程并设置返回值的地址(返回了num 的地址)
pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}
int main(int argc, char const *argv[])
{
// 创建线程
pthread_t t_id = -1 ;
pthread_create( &t_id , //新线程ID号
NULL , // 线程属性, NULL 默认属性
func, // 线程需要执行的例程(新线程需要执行的任务《函数》)
NULL ); // 线程的参数
printf("t_id : %ld\n" , t_id) ;
printf("这里是主函数,线程ID :%ld \n" , pthread_self() );
int * retval ;
int ret_val = 0 ;
sleep(1);
// pthread_cancel( t_id );
// 阻塞等待接合线程
printf("等待 function 线程退出:\n");
if( ret_val = pthread_join( t_id , (void*)&retval))
{
fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
}
printf("结合线程成功, 退出值为:%d\n" , *retval);
return 0;
}