gpt4 book ai didi

c# - 结构和结构集合的 volatile

转载 作者:太空狗 更新时间:2023-10-30 00:51:17 25 4
gpt4 key购买 nike

我想用网络智慧来澄清一些关于 .net 中多线程的时刻。互联网上有很多关于它的东西,但是我无法找到我的问题的好答案。

假设我们想在我们的类中维护一个状态,以保证并发线程的安全。简单的情况是状态为 int 时:

class Class1
{
volatile int state = 0;

public int State
{
get
{
return state;
}
}

public Action<int> StateUpdated;

public void UpdateState(int newState)
{
state = newState;

if (StateUpdated != null)
StateUpdated(newState);
}
}

'volatile' 在这种情况下应该足够了。无论线程需要获取当前状态,它都可以使用永远不会被缓存的“状态”属性。无论线程想要更​​新状态,它都可以使用“UpdateState”安全地完成。

但是,state是结构体怎么办?完全“锁定”是唯一的方法吗?附带问题:变量是否仍可以缓存在锁中?

struct StateData
{
//some fields
}

class Class1
{
StateData state;

public StateData State
{
get
{
return state;
}
}

public Action<StateData> StateUpdated;

public void UpdateState(StateData newState)
{
state = newState;

if (StateUpdated != null)
StateUpdated(newState);
}
}

最终的主要问题是:这段代码是否足以在多线程环境中管理一组状态对象?或者可能存在一些隐藏的问题。

public struct StateData
{
//some fields
}

public delegate void StateChangedHandler(StateData oldState, StateData newState);

class Class1
{
ConcurrentDictionary<string, StateData> stateCollection = new ConcurrentDictionary<string, StateData>();

public StateData? GetState(string key)
{
StateData o;

if (stateCollection.TryGetValue(key, out o))
return o;
else
return null;
}

public StateChangedHandler StateUpdated;

void UpdateState(string key, StateData o)
{
StateData? prev = null;

stateCollection.AddOrUpdate(key, o,
(id, old) =>
{
prev = old;

return o;
}
);

if (prev != null && StateUpdated != null)
StateUpdated(prev.Value, o);
}
}

感谢您的回答。

最佳答案

However, what to do if state is a structure? Is a complete 'lock' the only way?

volatile 关键字仅适用于可以原子更新的类型,例如引用类型变量、指针和基本类型。

但是,请注意 volatile 除了访问标记的变量之外还提供了一些保证。特别是,在写入标记为 volatile 的内存位置之前发生的所有内存写入操作都将被从同一 读取内存的任何代码看到>volatile——标记内存位置。

理论上,这意味着您可以使用 volatile 字段为其他内存位置提供类似 volatile 的行为。

但实际上,仍然存在一个问题:对相同内存位置的新写入可能可见,也可能不可见,当然并非所有写入都可以自动完成。所以这种 volatile 的使用实际上只对可以标记为 volatile 的其他内存位置有用,即使这样也不能确保你不会得到 更新 值,而不是标记为 volatile 的内存位置。

这是一个很长的说法,你应该只使用 lock 并完成它。 :)

Side question: can a variable still be cached inside the lock?

我不完全确定你问这个问题是什么意思。但总的来说:只要这些优化不影响在单个线程中观察到的代码行为,就允许编译器进行优化。如果您正在考虑的缓存类型不会违反此规则,则可能会被允许。否则就不会。

will this code be sufficient for managing a collection of state objects in multi-threading environment?

发布的代码看起来不错,至少就确保字典始终提供一致的状态值而言。

关于c# - 结构和结构集合的 volatile ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28925889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com