thread_specific_ptr 多线程混淆

Posted

技术标签:

【中文标题】thread_specific_ptr 多线程混淆【英文标题】:thread_specific_ptr multithread confusion 【发布时间】:2014-04-01 11:50:03 【问题描述】:

// 代码 sn -p 1

static boost::thread_specific_ptr<StreamX> StreamThreadSpecificPtr;
void thread_proc() 
    StreamX * stream = NULL;
    stream = StreamThreadSpecificPtr.get();
    if (NULL == stream) 

        stream = new StreamX();
        StreamThreadSpecificPtr.reset(stream);
    
    printf("%p\n", stream);

int run() 
    boost::thread_group threads;
    for(int i = 0; i < 5; i ++) 
        threads.create_thread(&thread_proc);
    
    threads.join_all();


// the result is 
0x50d560  -- SAME POINTER
0x50d540
0x50bfc0
0x50bef0
0x50d560  -- SAME POINTER

// 代码 sn -p 2

static boost::thread_specific_ptr<StreamX> StreamThreadSpecificPtr(NULL); // DIFF from code snippet 1
void thread_proc() 
    StreamX * stream = NULL;
    stream = StreamThreadSpecificPtr.get();
    if (NULL == stream) 

        stream = new StreamX();
        StreamThreadSpecificPtr.reset(stream);
    
    printf("%p\n", stream);

int run() 
    boost::thread_group threads;
    for(int i = 0; i < 5; i ++) 
        threads.create_thread(&thread_proc);
    
    threads.join_all();


// the result is
0x50d510
0x50d4f0
0x50bf70
0x50ca70
0x50be50

在代码 sn-p 1 中,两个指针是相同的。这不是预期的。 在代码 sn-p 2 中,将 StreamThreadSpecificPtr 初始化为 NULL,一切都很好。

您能帮忙找出这个困惑的答案吗?非常感谢。

【问题讨论】:

【参考方案1】:

令人高兴的是,您的线程实际上是异步终止的,从而破坏了 StreamX 实例。

使用检测器:

struct StreamX

    StreamX()  puts(__FUNCTION__); 
   ~StreamX()  puts(__FUNCTION__); 
;

我得到以下输出:

StreamX
0x7f258c0008c0
~StreamX
StreamX
0x7f25740008c0
~StreamX
StreamX
0x7f25840008c0
~StreamX
StreamX
0x7f25780008c0
StreamX
~StreamX
0x7f257c0008c0
~StreamX

real    0m0.002s
user    0m0.000s
sys 0m0.004s

后续分配重用相同的堆地址是有意义的,因为不涉及太多碎片。换句话说,您不能只比较指针来查看它们在并发应用程序中是否为同一个对象起别名。

与第二个示例的区别只是虚假的。有许多因素可以并且将会影响结果。例如。在每个线程的末尾添加一个微小的延迟将消除线程在其他实例被实例化之前终止的所有机会。

Live On Coliru

【讨论】:

总是很高兴看到你的答案。

以上是关于thread_specific_ptr 多线程混淆的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程编程中易混淆的3个关键字( volatileThreadLocalsynchronized)总结

[java面试必备]一文理解java多线程必备的sychronized关键字,从此不再混淆!

我链接到什么来定义boost :: thread_specific_ptr和相关的?

如何释放线程本地存储的堆内存

Java多线程

java多线程并发