模拟线程局部变量

时间:2013-10-24 11:00:41

标签: c++ multithreading thread-local

我想为非静态成员模拟线程局部变量,如下所示:

template< typename T, unsigned int tNumThread >
class ThreadLocal
{
private:

protected:
    T mData[tNumThread];

    unsigned int _getThreadIndex()
    {
        return ...; // i have a threadpool and each thread has an index from 0 to n
    }

public:
    ThreadLocal() {};
    ~ThreadLocal() {};

    T& operator ->()
    {
        return mData[_getThreadIndex()];
    }
    ...
};

但问题是线程的数量将在运行时确定,我必须从堆中分配mData

我想知道有没有办法不使用堆分配并使用上面的常规数组?

2 个答案:

答案 0 :(得分:1)

每个线程都有自己的堆栈,并且在函数返回时记住堆栈帧被弹出(或者可以被认为是弹出)。

这就是为什么我们有“无堆栈python”,因为1个堆栈(python需要什么)和多个线程不能很好(参见全局解释器锁)

你可以将它放在main中,这将持续,但请记住C(++)想知道COMPILE TIME的所有大小,所以如果线程数改变(在COMP COMPILE TIME没有修复)那就没办法了知道这一点。

你真正想要的不是主要内容,但这不是一个模板(在数字中),因为在编译时无法知道该数字。

GCC提供了一个堆栈分配功能(如malloc),但是我找不到它,最好避免使用它,因为那时优化实际上有效。

同样不要低估你的CPU预读能力和GCC优化,把数组放在堆上也不错。

有趣的阅读与良好的图片,但不幸的是只与该主题有很大关系: http://www.nongnu.org/avr-libc/user-manual/malloc.html

答案 1 :(得分:0)

我建议:

string UnicodeToGB2312(std::string uData)
{
    int len = strlen(uData.c_str()) + 1;
    char outch[MAX_PATH];
    WCHAR * wChar = new WCHAR[len];
    wChar[0] = 0;
    MultiByteToWideChar(CP_UTF8, 0, uData.c_str(), len, wChar, len);
    WideCharToMultiByte(CP_ACP, 0, wChar, len, outch, len, 0, 0);
    delete[] wChar;
    char* pchar = (char*)outch;
    return pchar;
}

要么你精确地锁定所有访问,要么提前准备人口并在以后阅读它。

您可以将它与堆栈分配器结合使用。

std::unordered_map<std::thread::id, T, stackalloc> myTLS;

https://howardhinnant.github.io/stack_alloc.html

如果您想要其他解决方案,请执行以下操作:

typedef short_alloc<pair<const thread::id, T>, maxthrds> stackalloc;

对于MESI无瓶颈访问。
您将不得不关心使用此方法在此数组中使用自己的索引跟踪线程。