【问题标题】:Static initialization in c++ and thread safetyC++中的静态初始化和线程安全
【发布时间】:2012-11-12 05:09:30
【问题描述】:

类实例的静态初始化不是线程安全的。下面的代码是一个不应该做的例子:

extern int computesomething();

class cachedcomputation
{
public:
    cachedcomputation()
    {
        result = computesomething();
    }

    int result;
};

void usecached()
{
    static cachedcomputation c;

    // use of c.result - may break
}

但是,下面的代码是线程安全的吗? (忽略解决方案的丑陋)它何时或为什么会中断?

extern int computesomething();

class cachedcomputation
{
public:
    cachedcomputation()
    {
    if(0==InterlockedCompareExchange(&mutex, 1, 0))
    {
        // first thread
            result = computesomething();
        InterlockedExchange(&mutex, 2);
    }
    else
    {
        // other thread - spinlock until mutex==2
        while(2!=InterlockedCompareExchange(&mutex, 2, 2)){}
    }
    }

    int result;

private:
    long mutex;
};

void usecached()
{
    static cachedcomputation c;

    // use of c.result - ???
}

【问题讨论】:

    标签: c++ multithreading static thread-safety


    【解决方案1】:

    你需要:

    • 初始化您的“互斥锁”
    • 在 if 块末尾重置“mutex”:InterlockedExchange(&mutex, 0)
    • 可选择将 if 语句转换为 while,这样您的代码将一直阻塞,直到“互斥锁”解锁

    【讨论】:

    • 1 - 静态应该默认设置为 0 吗? 2&3 - 我希望只调用一次 computesomething。修改解决方案以将其考虑在内并使其更清晰
    • long mutex 本身不是静态的,并且从未分配过。 cachedcomputation() : mutex(0) 是一种初始化 mutex 的干净方式。
    • @MichaelSh 为什么要将“mutex”重置为零?
    • 不需要重置,因为computesomething 只需要调用一次。不过,仍需要将 mutex 初始化为零。
    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 2010-10-27
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    相关资源
    最近更新 更多