欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

linux:分离线程

程序员文章站 2022-05-01 20:22:19
...

为什么要分离线程?

1.默认情况下,新创建的线程是joinable的,线程退出后,需对其进行pthread_join操作,否则无法释放资源,从而造成系统泄露
2.如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源

分离线程的目的

让线程自生自灭,自动释放线程
ps:但是,如果把一个线程设为分离的线程,一定要在主线程中循环的等待一下新创建的线程执行,否则就会出现,新创建的线程还没执行结束呢,主线程已经执行结束了

例如:
1.创建新线程,把新创建的线程设置为分离线程

#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<pthread.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<netinet/in.h>
void* ThreadEnter1(void* addr)
{
    struct sockaddr_in* addr1=(struct sockaddr_in*)addr;
    char* ptr1=inet_ntoa(addr1->sin_addr);
    printf("addr1:%s\n",ptr1);
    return NULL;
}
void*ThreadEnter2(void*addr)
{
    struct sockaddr_in* addr2=(struct sockaddr_in*)addr;
    char* ptr2=inet_ntoa(addr2->sin_addr);
    printf("addr2:%s\n",ptr2);
    return NULL;
}
int main()
{
    pthread_t tid1,tid2;
    struct sockaddr_in addr1;
    struct sockaddr_in addr2;
    addr1.sin_addr.s_addr=0;
    addr2.sin_addr.s_addr=0xffffffff;
    pthread_create(&tid1,NULL,ThreadEnter1,&addr1);
    pthread_create(&tid2,NULL,ThreadEnter2,&addr2);
    pthread_detach(tid1);
    pthread_detach(tid2);
    return 0;
}

运行结果:
linux:分离线程
结果解析:因为没有在主线程中等待新线程,而主线程又执行的太快,导致新创建的线程还没执行完呢,主线程就已经结束了,所以没有输出任何内容

2.创建新线程,把新创建的线程设置为分离线程,并在主线程中等待新创建的线程

#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<pthread.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<netinet/in.h>
void* ThreadEnter1(void* addr)
{
    struct sockaddr_in* addr1=(struct sockaddr_in*)addr;
    char* ptr1=inet_ntoa(addr1->sin_addr);
    printf("addr1:%s\n",ptr1);
    return NULL;
}
void*ThreadEnter2(void*addr)
{
    struct sockaddr_in* addr2=(struct sockaddr_in*)addr;
    char* ptr2=inet_ntoa(addr2->sin_addr);
    printf("addr2:%s\n",ptr2);
    return NULL;
}
int main()
{
    pthread_t tid1,tid2;
    struct sockaddr_in addr1;
    struct sockaddr_in addr2;
    addr1.sin_addr.s_addr=0;
    addr2.sin_addr.s_addr=0xffffffff;
    pthread_create(&tid1,NULL,ThreadEnter1,&addr1);
    pthread_create(&tid2,NULL,ThreadEnter2,&addr2);
    pthread_detach(tid1);
    pthread_detach(tid2);
    while(1){
        printf("I am main\n");
        sleep(1);
    }
    return 0;
}

运行结果:
linux:分离线程
结果解析:这次在主线程中循环的等待新创建的线程了,所以新创建的线程的代码都执行完了,故输出了我们想要的结果 (while循环的目的就是为了等待新创建的线程)

释放线程ID为thread的线程

int pthread_detach(pthread_t thread)

释放当前线程

int pthread_detach(pthread_self())
ps:pthread_self()可以得到当前线程的ID

1.一个可结合的线程能够被其他线程收回资源和杀死,在被其他线程回收之
   前,它的存储器资源(如栈)是不释放的

2.一个分离的线程是不能被其他线程回收,它的存储器资源在
   它终止时由系统自动释放  

joinable(可结合的)和detach(分离)是冲突的,一个线程不能既是joinable又是分离的,在默认情况下,线程是非分离状态的

总结

1.pthread_join是等待线程执行结束后,此线程占有的资源被其他线程回收
ps:如果想要得到线程的返回值或者不想让线程再继续执行,选择pthread_join

2.pthread_detach是把此线程设置为分离线程,此线程执行结束后,此线程占
有的资源,会由系统自动回收

示例

设置线程ID为tid的线程为分离线程

1.

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int count=0;
    while(1)
    {
        ++count;
        if(count>=5)
            pthread_exit(NULL);
        printf("I am thread\n");
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,ThreadEntry,NULL);
    pthread_detach(tid);//把线程ID为tid的线程设置成分离线程,
    //此线程运行结束后,系统会自动释放此线程占有的资源
    while(1)
    {
     printf("I am main\n");
     sleep(1);
     }
    return 0;
}

运行结果:
linux:分离线程
2.
代码:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    while(1)
    {
        printf("I am thread\n");
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    int count=0;
    pthread_create(&tid,NULL,ThreadEntry,NULL);
    pthread_detach(tid);//把线程ID为tid的线程设置成分离线程,
    //此线程运行结束后,系统会自动释放此线程占有的资源
    while(1)
    {
        ++count;
        if(count>=4)
            pthread_cancel(tid);
        printf("I am main\n");
        sleep(1);
    }
    return 0;
}

运行结果:
linux:分离线程

3.把当前线程设置为分离线程(设置为分离线程后,此线程执行结束后,系统会自动回收此线程占有的资源)
代码:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int count=0;
    while(1)
    {
        ++count;
        if(count>=4)
            pthread_exit(NULL);
        printf("I am thread\n");
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    int count=0;
    pthread_create(&tid,NULL,ThreadEntry,NULL);
    pthread_detach(pthread_self());//把当前线程设置成分离线程,
    //此线程运行结束后,系统会自动释放此线程占有的资源
    while(1)
    {
        ++count;
        if(count>=6)
            pthread_cancel(pthread_self());
        printf("I am main\n");
        sleep(1);
    }
    return 0;
}

运行结果:
linux:分离线程

ps:即就是说,现在有一个线程,pthread_join和pthread_detach都是回收此线程占有的资源的,而pthread_join是由其他线程回收此线程占有的资源的,如果把此线程设置为分离线程(pthread_detach),那此线程占有的资源就是由系统进行自动回收的

相关标签: 线