当前位置 : 主页 > 编程语言 > java >

问题解决:如何管理线程私有(thread_local)的指针变量

来源:互联网 收集:自由互联 发布时间:2022-07-04
引言 问题出现在实现项目的一个功能的时候,我需要一个thread_local的指针,因为整个项目已经差不多实现了,但在最后发现了内存泄露的问题。因为实现的是一个偏向于底层的库,且内

引言

问题出现在实现项目的一个功能的时候,我需要一个thread_local的指针,因为整个项目已经差不多实现了,但在最后发现了内存泄露的问题。因为实现的是一个偏向于底层的库,且内存的使用基本都在掌握之内,所以在项目实现之初为了效率并没有使用智能指针,但在后来在这里出现了内存泄露问题。

原本代码差不多是这样:

__thread Co_Rountinue_Env* CurrentThread_CoEnv = nullptr;

这样在线程结束以后很难去把它释放掉,所以需要想一个方法做到这样,且不想大规模改动原有代码,最终的解决方案是这样的:

__thread Co_Rountinue_Env* CurrentThread_CoEnv = nullptr;

thread_local std::unique_ptr<Co_Rountinue_Env, decltype(Free_Co_Rountinue_Env)*>
DeleteThread_CoEnv(CurrentThread_CoEnv, Free_Co_Rountinue_Env);

不必在意变量名,基本思路还是使用智能指针去管理内存,我们来看一个模拟的小demo:

#include <bits/stdc++.h>
#include <unistd.h>
using namespace std;

void Delete_(int* para){
if(para == nullptr) return;
cout << "nihao\n";
delete para;
return;
}
thread_local int* env = nullptr;

thread_local std::unique_ptr<int, decltype(Delete_)*>
Env(env, Delete_);

void* Routine(void* para){
Env.reset();
env = new int(5);
Env.reset(env);
cout << "函数结束\n";
return 0;
}

int main(){
pthread_t tid[5];
for(size_t i = 0; i < 2; i++){
pthread_create(tid + i, nullptr, Routine, 0);
}
for(size_t i = 0; i < 2; i++){
pthread_join(tid[i], nullptr);
}
sleep(1);
return 0;
}

输出:

函数结束
nihao
函数结束
nihao

这样就达到了预期。


在解决问题的过程中还发现了boost库中也有一个玩意儿可以做到这样,即​​boost::thread_specific_ptr​​,它的作用就是用于每线程存储,且会在线程结束的时候执行预先设置的回调,就类似于一个特殊的智能指针,我们来看看其如何应用:

#include <bits/stdc++.h>
#include <boost/thread/tss.hpp>
#include <unistd.h>
using namespace std;

void Delete_(int* para){
if(para == nullptr) return;
cout << "nihao\n";
delete para;
return;
}

boost::thread_specific_ptr<int> env {&Delete_};

void* Routine(void* para){
if(!env.get()){
env.reset(new int(5));
}
cout << *env << endl;
cout << "函数结束\n";
return 0;
}

int main(){
pthread_t tid[5];
for(size_t i = 0; i < 2; i++){
pthread_create(tid + i, nullptr, Routine, 0);
}
for(size_t i = 0; i < 2; i++){
pthread_join(tid[i], nullptr);
}
sleep(1);
return 0;
}

执行以下命令:

g++ XXX.cpp -pthread -lboost_system -lboost_thread
./a.out

我们可以在使用时把​​thread_specific_ptr​​当做普通指针来用,因为其本身的成员函数并不多,相比与智能指针来说可谓一个天上一个地下。除去对于指针值的输出,我们可以看到其他输出都是一样的:

5
函数结束
nihao
5
函数结束
nihao

对thread_specific_ptr有兴趣的朋友可以去看看其文档,链接在文末。

参考:

  • 文档《​​boost::thread_specific_ptr​​》


【转自:美国高防服务器 http://www.558idc.com/usa.html转载请说明出处】
上一篇:新版本的github如何查看贡献者(Contributors)
下一篇:没有了
网友评论