线程的等待与分离总结

哈哈 阅读:4126 2021-05-14 10:25:16 评论:0

一、线程等待
1、为什么需要线程等待?
因为已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。创建新的线程不会复用刚才退出线程的地址空间。

2、线程等待函数–pthread_join
(1)功能:等待线程结束
(2)原型:int pthread_join(pthread_t pthread, void **value_ptr);
(3)参数:
1)thread:线程ID;
2)Value_ptr:它指向一个指针,后者指向线程的返回值。
(4)返回值:成功返回0;失败返回错误码。

3、线程终止状态
调用pthread_join函数的线程将挂起等待,直到ID为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
(1)如果thread线程通过return返回,value_ptr所指向的单元里存放的是thread线程函数的返回值。
(2)如果thread线程被别的线程调用pthread_cancel异常终止,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED。
(3)如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
(4)如果对thread线程的终止状态不感兴趣,可以传NULL给value_ptr参数。
这里写图片描述
【例】

#include<stdlib.h> 
#include<stdio.h> 
#include<string.h> 
#include<pthread.h> 
#include<unistd.h> 
 
void *thread1(void *arg) 
{ 
    printf("thread 1 returning...\n"); 
    int *p = (int *)malloc(sizeof(int)); 
    *p = 1; 
    return (void*)p; 
} 
 
void *thread2(void *arg) 
{ 
    printf("thread 2 exiting ...\n"); 
    int *p = (int *)malloc(sizeof(int)); 
    *p = 2; 
    pthread_exit((void*)p); 
} 
 
void *thread3(void *arg) 
{ 
    while(1){ 
        printf("pthread 3 running ...\n"); 
        sleep(1); 
    } 
    return NULL; 
} 
 
int main(void) 
{ 
    pthread_t tid; 
    void *ret; 
 
    //thread 1 return 
    pthread_create(&tid, NULL, thread1, NULL); 
    pthread_join(tid, &ret); 
    printf("thread return, thread id %X, return code:%d\n", tid, *(int*)ret); 
    free(ret); 
 
    //thread 2 exit 
    pthread_create(&tid, NULL, thread2, NULL); 
    pthread_join(tid, &ret); 
    printf("thread return, thread id %X, return code:%d\n", tid, *(int*)ret); 
    free(ret); 
 
    //thread 3 cancel by other 
    pthread_create(&tid, NULL, thread3, NULL); 
    sleep(3); 
    pthread_cancel(tid); 
    pthread_join(tid, &ret); 
    if(ret == PTHREAD_CANCELED) 
        printf("thread return, thread id %X, return code:PTHREAD_CANCELED\n", tid); 
    else 
        printf("thread return, thread id %X, return code:NULL\n", tid); 
}

运行结果:
这里写图片描述

二、分离线程
1)默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成内存泄漏。
2)如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
int pthread_detach(pthread_t pthread);
可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离;pthread_detach(pthread_self());
joinable和分离是冲突的,一个线程不能既是joinable又是分离的。
【例】

#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include<string.h> 
#include<pthread.h> 
 
void *thread_run(void *arg) 
{ 
    pthread_detach(pthread_self()); 
    printf("%s\n", (char*)arg); 
    return NULL; 
} 
 
int main() 
{ 
    pthread_t tid; 
    if(pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0){ 
        printf("create thread error\n"); 
        return 1; 
    } 
 
    int ret = 0; 
    sleep(1); 
 
    if(pthread_join(tid, NULL) == 0){ 
        printf("pthread wait success\n"); 
        ret = 0; 
    }else{ 
        printf("pthread wait failed\n"); 
        ret = 1; 
    } 
    return ret; 
}

运行结果为:
这里写图片描述


声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

全民解析

全民解析

关注我们