在TlsSetValue

时间:2017-06-30 06:12:37

标签: c++ thread-local-storage

在我的C ++ DLL中,我使用Thread本地存储来存储和检索特定于线程的信息。

特定于线程的信息被打包在对象pInfo中。我在DLL附件中分配一次,然后使用TlsSetValue为每个线程存储pInfo。

PInfo *pInfo = TlsGetValue(tlsIndex);
if(pInfo == NULL)
{
   pInfo = new PInfo();
   errCheck = TlsSetValue(tlsIndex, pInfo);
}

经过一些函数回调并填充pInfo。在特定点,我将此pInfo(指针)推送到静态向量(定义如下)。

vector<PInfo*>* swapBucket;

使用swapBucket->push_back(pInfo);我推送此对象。推送之后,我需要刷新现有的TLS索引存储。所以我正在为现有的TLS索引分配NULL。

errCheck = TlsSetValue(tlsIndex, NULL);

设置完成后,我验证swapBucket中最后插入的pInfo是否有效。但令人惊讶的是它是NULL。

       if(swapBucket->size() > 0)
        {
            if(swapBucket->back() == NULL)
            {
                fileLogObj->WriteLog("[WARNING]","Last Element is NULL",2);
            }
        }

这不会一直发生。只有一些时间发生。 (可能是一次5000次 - 有时它永远不会发生)。大多数情况下,无论我推入向量中的任何对象都保持相同(即使在使用TlsSetValue刷新之后)。为什么被推送的对象变为NULL。 (我也没有删除对象 - 在使用那些矢量对象进行一些处理后,我删除了那些pInfos)

1 个答案:

答案 0 :(得分:0)

虽然无法从您的问题中说出究竟是什么问题,但是当您使用线程有时这些词来描述问题时,很可能是您的问题。在某处错过了一些同步。

例如,std::vector不是线程安全的。您需要确保对其进行顺序访问,例如使用互斥锁:

#include <mutex>

std::mutex swapBucketMtx;
std::vector<PInfo*>* swapBucket;

{
    // First lock the mutex
    std::lock_guard<std::mutex> swapBucketLock(swapBucketMtx);

    // Now you may access swapBucket
    swapBucket->push_back(pInfo);
    if(swapBucket->size() > 0)
    {
        if(swapBucket->back() == NULL)
        {
            fileLogObj->WriteLog("[WARNING]","Last Element is NULL",2);
        }
    }

    // mutex will unlock automatically on scope exit
}