pthread的和std::thread的线程分离

本文详细介绍了C++11线程分离的概念及其与内存泄露的关联,通过实例展示了如何使用pthread_join和pthread_detach处理线程资源回收,并提供了C++11中更简洁的线程分离方式及注意事项,包括异常机制处理和内存泄露检测方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <error.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>


void work1(void *arg)
{
    char *mem1 = (char *)malloc(100);
    free(mem1);
}

void work2(void *arg)
{
    char *mem2 = (char *)malloc(100);
    free(mem2);
}

int main()
{
    pthread_t thread_id1, thread_id2;
    pthread_create(&thread_id1, NULL, (void *)work1, NULL);
    pthread_create(&thread_id2, NULL, (void *)work2, NULL);

    //pthread_detach(thread_id1);
    pthread_join(thread_id2, NULL);
    sleep(3);
    printf("%ld %ld", thread_id1, thread_id2);
    return 0;
}


对pthread传统要用pthread_join函数等待其结束,实际上pthread_join函数还有另一个功能:清理线程的资源。

因为有时候开启线程后并不关心线程什么时候结束,此时就需要使用pthread_detach来将线程分离。被分离的线程将由操作系统自动回收其资源。

也就意味着上述代码出现了一处内存泄露,因为线程1既没有被分离,也没有使用pthread_join等待其完成。

PS:(1)操作系统只会回收线程本身的资源开销,并不会回收线程在堆上分配的内存。假如将函数work1和work2中的内存释放语句free注释掉的话,本例中的内存泄露将会达到三处。

         (2)内存泄露可使用valgrind --tool=memcheck --leak-check=full ./a.out来检测。检测前必须安装valgrind且程序编译要加上-g选项。

         (3)线程在创建的时候可将属性设置为分离,这样就自动具备了分离属性,就无需显示调用pthread_detach了。


下面来看C++11中的线程的分离。与pthread原理类似。

#include <iostream>
#include <thread>
using namespace std;

void work()
{
    cout << std::this_thread::get_id() << endl;
}

int main()
{
    thread t1(work);
    thread t2(work);
    t1.join();
    t2.detach();
    return 0;
}

代码是不是简洁了不少?

需要注意的是不管是将线程t1的join函数注释,或是将t2的detach注释掉,程序都会崩溃。为什么呢?

因为C++有异常机制,而本例中没有对异常进行捕获。


以上两个例子测试系统是ubuntu 14.04.3,gcc(g++)的版本是4.6.3。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值