7

我想使用 WinAPI 中的 InterlockedExchange 来使用线程的无锁同步。
目前我有这样的课。

struct DataExchange
{
    volatile LONG m_value;
    void SetValue(LONG newVal)
    {
        InterlockedExchange(&m_value, newVal);
    }

    LONG GetValue()
    {
        LONG workVal=0;
        InterlockedExchange(&workVal, m_value);
        return workVal;
    }
};

一个线程可以设置一个新值,而另一个线程可以读取该值。
现在我想做的是将LONG值更改为struct. WinAPI中有什么方法可以struct免费复制锁吗?

4

4 回答 4

3

不,除非您可以将您的结构放入 32 位,在这种情况下您可以继续使用 InterlockedExchange。

于 2011-05-24T11:43:23.690 回答
2

您可以在 64 位平台和 Windows Vista/7 上使用InterlockedExchange64对 64 位值进行原子操作。这足以int在一个结构中容纳两个 32 位值。

由于该函数是使用编译器内在实现的,因此它基本上是在调用与CMPXCHGx86 类似的平台相关的汇编指令。由于该指令最多只能在 64 位寄存器源操作数、64 位寄存器或内存目标操作数和寄存器上工作(在 64 位平台上)RAX,因此您只能执行特定大小的值使用单个汇编指令的原子操作,无需结合某种类型的锁或信号量来创建临界区。

于 2011-05-24T12:20:45.177 回答
1

仅当结构正好是 32 位时。

另一种方法是在指向结构的指针上使用 InterlockedExchange。结构必须是不可变的(或永远不会改变它)。要更新结构,请创建一个新结构,然后交换指针。您必须小心销毁结构以确保它只执行一次,并且只有在没有人使用它的情况下。

于 2011-05-24T11:45:06.687 回答
1

如果可以足够快地获得所有权,您可以做的最好的事情是使用InitializeCriticalSectionAndSpinCount不会等待锁定的功能。

于 2011-05-24T11:52:15.113 回答