11、操作系统——线程的属性(3)(压栈、弹栈)

目录

一、压栈、或弹栈线程的取消处理例程

1、原因

2、相关API

​3、代码

一、压栈、或弹栈线程的取消处理例程

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

猜你喜欢

转载自blog.csdn.net/weixin_45981798/article/details/129877017