您的位置:首页 > 运维架构 > Linux

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

2016-03-25 01:36 369 查看
#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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息