如何在不使用锁的情况下使一组操作原子化
How to make group of operations atomic without using Lock
我有一个 state
变量,其感兴趣的字段是 thread-safe
并使用 ReaderWriterLockSlim
保持 fresh
。我已经细化了对所有字段的访问,因为我在其他地方单独使用它们。
虽然对于单独访问字段它工作正常,但我还需要进行一些操作 atomic.In 这种情况下我需要额外的 lock
吗?
我有一个已经包含 thread-safe
个字段的状态变量:
internal class State {
private ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
private bool cmd_PopUp;
private bool cmd_Shutdown;
private bool cmd_Delay;
public bool CMD_PopUp {
get {
try {
this.lck.EnterReadLock();
return this.cmd_PopUp;
} finally {
this.lck.ExitReadLock();
}
}
set {
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = value;
} finally {
this.lck.ExitWriteLock();
}
}
}
//same goes for the other booleans
}
我已经有了这个线程安全的,而且我确保线程从内存中读取而不是从本地读取cache.However我需要多个操作以原子方式完成。
原子操作
public async Task Run(State state)
{
while(true)
{
//do i need a lock here
if (state.CMD_Delay) {
state.CMD_Delay = false;
state.CMD_PopUp = false;
//end of potential lock ?
} else if (state.CMD_Shutdown) { //same here
state.CMD_PopUp = false;
state.CMD_Shutdown = false;
await SomeAction();
}
}
}
正如你在我的 while
中看到的那样,我有一个 if-else
,我需要一组操作是原子的。我应该使用额外的 lock
还是有一些其他的轻量级解决方案 ?
re-use 你现有的锁对我来说最有意义:
internal class State
{
...
public void SetDelayState()
{
try {
this.lck.EnterWriteLock();
this.cmd_Delay = false;
this.cmd_PopUp = false;
} finally {
this.lck.ExitWriteLock();
}
}
public void SetShutdownState()
{
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = false;
this.cmd_Shutdown = false;
} finally {
this.lck.ExitWriteLock();
}
}
}
换句话说,将所有原子操作移动到您的 State
类型的成员。
旁注:您几乎肯定不需要 reader/writer 锁。 Reader/writer 仅当满足以下 所有 条件时才应使用锁:
- 部分代码路径为 read-only,其他为 read/write。
- 读者远远多于作者。
- 连续阅读人数较多
如果 任何 不正确,那么 lock
是更好的选择。
我有一个 state
变量,其感兴趣的字段是 thread-safe
并使用 ReaderWriterLockSlim
保持 fresh
。我已经细化了对所有字段的访问,因为我在其他地方单独使用它们。
虽然对于单独访问字段它工作正常,但我还需要进行一些操作 atomic.In 这种情况下我需要额外的 lock
吗?
我有一个已经包含 thread-safe
个字段的状态变量:
internal class State {
private ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
private bool cmd_PopUp;
private bool cmd_Shutdown;
private bool cmd_Delay;
public bool CMD_PopUp {
get {
try {
this.lck.EnterReadLock();
return this.cmd_PopUp;
} finally {
this.lck.ExitReadLock();
}
}
set {
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = value;
} finally {
this.lck.ExitWriteLock();
}
}
}
//same goes for the other booleans
}
我已经有了这个线程安全的,而且我确保线程从内存中读取而不是从本地读取cache.However我需要多个操作以原子方式完成。
原子操作
public async Task Run(State state)
{
while(true)
{
//do i need a lock here
if (state.CMD_Delay) {
state.CMD_Delay = false;
state.CMD_PopUp = false;
//end of potential lock ?
} else if (state.CMD_Shutdown) { //same here
state.CMD_PopUp = false;
state.CMD_Shutdown = false;
await SomeAction();
}
}
}
正如你在我的 while
中看到的那样,我有一个 if-else
,我需要一组操作是原子的。我应该使用额外的 lock
还是有一些其他的轻量级解决方案 ?
re-use 你现有的锁对我来说最有意义:
internal class State
{
...
public void SetDelayState()
{
try {
this.lck.EnterWriteLock();
this.cmd_Delay = false;
this.cmd_PopUp = false;
} finally {
this.lck.ExitWriteLock();
}
}
public void SetShutdownState()
{
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = false;
this.cmd_Shutdown = false;
} finally {
this.lck.ExitWriteLock();
}
}
}
换句话说,将所有原子操作移动到您的 State
类型的成员。
旁注:您几乎肯定不需要 reader/writer 锁。 Reader/writer 仅当满足以下 所有 条件时才应使用锁:
- 部分代码路径为 read-only,其他为 read/write。
- 读者远远多于作者。
- 连续阅读人数较多
如果 任何 不正确,那么 lock
是更好的选择。