← 返回首页
Linux高级程序设计(七十二)
发表时间:2021-12-24 15:40:27
线程分离

1.线程状态

linux线程执行和windows不同,pthread有两种状态joinable(结合)状态和detached(分离)状态。如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。相反,一个分离态的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。Linux线程默认使用结合态。

其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦。

函数原型: pthread_detach函数可回收创建的子线程的存储空间。该函数不会阻塞父线程。

#include <pthread.h>

int pthread_detach(pthread_t tid);

参数: - tid:线程标识符

返回值: - 成功返回0,失败返回非0。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *thr_fn(void *arg)
{
    //尽量不要使用栈区的变量,比如int status=666;
    static int status = 666;
    printf("son thread is running...\n");
    sleep(3);
    printf("************son thread will exit************\n");
    return (void *)&status;
}

int main(int argc, char const *argv[])
{
    printf("main thread is running....\n");
    pthread_t thread;

    if (pthread_create(&thread, NULL, thr_fn, NULL) != 0)
    {
        perror("error to pthread_create:");
        exit(-1);
    }


    if (pthread_detach(thread) != 0)
    {
        perror("error to detach:");
        exit(-1);
    }

    /*
    int *status;
    //等待子线程的结束
    //默认是结合态必须使用pthread_join释放资源,由于这个方法是阻塞的,导致主线程后面代码无法执行。
    if (pthread_join(thread, (void **)&status) != 0)
    {
        perror("error to join:");
        exit(-1);
    }
    printf("return status=%d\n",*status);
    */

    while (1)
    {
        printf("hello,world!\n");
        sleep(1);
    }

    return 0;
}

执行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
main thread is running....
hello,world!
son thread is running...
hello,world!
hello,world!
************son thread will exit************
hello,world!
hello,world!
hello,world!
hello,world!
^Z