Interlocked Exchange of a struct
I want to use InterlockedExchange from the WinAPI to use a lock free synchronization of threads.
At the moment I have a class like this.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;
}
};
One thread can set a new value and an other thread can read this value.
Now what I want to do is to change t开发者_如何学JAVAheLONG
value to be a struct
.
Is there any way in the WinAPI how I can copy a struct
lock free?No there isn't unless you can fit your struct into 32 bits, in which case you can continue to use InterlockedExchange.
You can get an atomic operation on a 64-bit value using InterlockedExchange64 on 64-bit platforms and Windows Vista/7. That would be enough to fit two 32-bit int
values in a struct.
Since the function is implemented with a complier instrinsic, it's basically calling a platform-dependent assembly instruction like CMPXCHG
on x86. Since that instruction only works at a maximum (on 64-bit platforms) on a 64-bit register source operand, a 64-bit register or memory destination operand, and the RAX
register, there is only a certain-size value you can perform an atomic operation on using single assembly instructions without incorporating some type of lock or semaphore to create a critical section.
Only if the struct is exactly 32 bits.
An alternative is to use an InterlockedExchange on a pointer to a struct. The struct has to be immutable (or never change it). To update the struct, make a new one and then exchange the pointer. You have to be careful about destroying the struct to make sure it is only done once, and only if no one is using it.
The best you can do is to use InitializeCriticalSectionAndSpinCount
function which will not wait for the lock if it is possible to take an ownership fast enough.
精彩评论