linux:分离线程

为什么要分离线程?

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

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

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

运行结果:
这里写图片描述
结果解析:这次在主线程中循环的等待新创建的线程了,所以新创建的线程的代码都执行完了,故输出了我们想要的结果 (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;
}

运行结果:
这里写图片描述
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;
}

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

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

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

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

猜你喜欢

转载自blog.csdn.net/dangzhangjing97/article/details/79874595
今日推荐