• Linux多线程C++版(三) 线程终止 pthread_cancel()函数 pthread_exit()函数 pthread_join()函数


    1.线程终止基础
    • 主动终止
      • 线程的执行函数中调用return语句
      • 调用pthread_exit()
    • 被动终止
      • 线程可以被同一进程的其他线程取消,其他线程调用pthread_cancel(pthid)
    2.线程终止
    #include
    int pthread_cancel(pthread_ tid);
    void pthread_exit(void *retval);
    int pthread_join(pthread_ th,void **thread_return);
    返回:成功为0 否则为非零 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3.pthread_cancel 函数
    • int pthread_cancel(pthread_ tid);

    • 线程可以被同一进程的其他线程取消,tid为要终止的线程标识符

    4.pthread_exit 函数
    • *void pthread_exit(void retval);

    • retval:线程创建时,需要运行函数,pthread_exit 的参数就为这个函数的返回值,可由其他函数和pthread_join来检测获取

    • 线程退出时使用函数pthread_exit,是线程的主动行为

    • 由于一个进程中的多个线程共享数据段,因此通常在线程退出后,退出线程所占用的资源并不会随线程结束而释放。如果想要立即释放就必须在主控线程中使用pthread_join函数来等待线程结束,这样线程才会释放干净。

    5.pthread_join函数
    • *int pthread_join(pthread_ th,void * thread_return);

    • th:要等待线程的标识符

    • thread_return(是一个二阶指针):用户定义指针,用来存储要等待线程的返回值

    • 作用:谁调用谁阻塞,直到第一个参数的线程执行完毕

    • 举例:pthread_join(rabbit, NULL); pthread_join是主控线程调用的,表示自己会阻塞,直到rabbit线程结束 主控线程方可运行

    以上函数在代码实例:

    #include
    #include
    #include
    #include
    //定义结构体
    typedef struct{
        int d1;
        int d2;
    }Arg;
    //定义线程运行函数
    void* th_fn(void* arg) {
    	//void* arg 传过来具体参数是结构体指针 要用需要强制转换成结构体
    	RaceArg *r = (RaceArg*)arg;
        
        //返回值值是一个数据类型
    	//return (r->d1+r->d2); 可以用pthread_exit()函数代替,参数为函数的返回值
        pthread_exit((void*)(r->d1+r->d2));
        
        //可以返回结构体指针
        return (void*)r;
    }
    int main(void){
        
        //用于接收线程是否创建成功的返回值
    	int err;
        
    	//定义线程标识符rabbit turtle
    	pthread_t th;
        
        //结构体赋值
        Arg r = {10,60};
        
        //创建rabbit线程,并给与赋值
    	if ((err = pthread_create(&r, NULL, th_fn, (void*)&r)) != 0) {
    		perror("pthread_create error");
    	}
        
        //返回值值是一个数据类型
        //用来存放r线程调用函数的返回值
        int *result;
        //阻塞主线程,等待r结束 第二个参数是用于存放函数的返回值
        pthread_join(r,(void**)&result);
    	//输出的是主控线程的ID
    	printf("result is %d\n", (int)result);
        
        //另一种方式
        int result;
        pthread_join(r,(void*)&result);
        printf("result is %d\n", result);
    	
        
        //当返回值值是一个结构体指针
        int *result;
        pthread_join(r,(void**)&result);
        printf("result is %d\n", (Arg*)result->d1+(Arg*)result->d2);
        
         //另一种方式
        int result;
        pthread_join(r,(void**)&result);
        printf("result is %d\n", (Arg*)result->d1+(Arg*)result->d2);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    基于php柚子商城
    【fairseq】RuntimeError: Unrecognized tensor type ID: AutogradCUDA
    【java面试】Redis篇
    数据之道读书笔记-05面向“联接共享”的数据底座建设
    Node.js浅学
    忘记 iPhone 密码:如果忘记密码,如何解锁 iPhone
    剑指offer(C++)-JZ39:数组中出现次数超过一半的数字(算法-其他)
    图数据库Neo4j详解
    【并发编程三】C++进程通信(管道pipe)
    PCL 基于任意四点计算球心坐标
  • 原文地址:https://blog.csdn.net/kaszxc/article/details/127929427