有没有办法在c#中没有上下文切换的情况下强制执行原子操作?

时间:2009-04-20 18:28:06

标签: c# .net multithreading

我有几行方法,我想确保在执行这些方法时没有上下文切换到另一个线程?是的,重新架构是一种选择,但如果我能做到这一点,现在会更加便利。

这可能吗?如果没有,那么有人知道决定背后的原因吗?

编辑:我问的原因是我有一个负责返回值的类,该值是通过事件提供的,所以当调用GetValue()时,线程需要阻塞直到事件被提出。所以我们有:

public class ValueResolver {
  IPersistentNotifier _notifier;
  IValueMonitor _monitor;
  Value _value;
  ManualResetEvent _resolvedEvent = new ManualResetEvent(false);
  public ValueResolver(IPersistentNotifier notifier, IValueMonitor monitor) {
    _notifier = notifier;
    _monitor = monitor;
    _monitor.ValueAcquired += ValueAcquired;
  }
  public Value GetValue() {
    _value = null;
    persistentNotifier.Show("Getting Value")
    _monitor.Start();
    _resolvedEvent.WaitOne(60000, false);
    return _value
  }
  public void ValueAcquired(Value val) {
    _value = val;
    _monitor.Stop();
    _notifier.Hide();
    _resolvedEvent.Set();
  }
}

我只能想到为此编写测试就像(在犀牛嘲笑中)

var monitor = MockRepository.GetMock<IValueMonitor>() 
monitor.Expect(x=>x.Start()).Do(new Action(() => {
  Thread.Sleep(100);
  monitor.Raise(y=>y.ValueAcquired, GetTestValue());
}); 

但欢迎任何建议。

4 个答案:

答案 0 :(得分:9)

不,你不能。你可以使用一个锁来确保没有其他线程会输入敏感的代码片段来处理你的操作,但就是这样。

至于“为什么” - 通常不需要它,并且在相对高级平台上的先发制人操作系统中会略显奇怪。它可能在驱动程序代码中,但在用户代码中通常不需要它。

请注意,“运行其他线程”并不一定意味着在多核和多处理器计算机的情况下进行上下文切换。

编辑:尽管你的编辑,我仍然不明白为什么这是一个上下文切换的问题。如果线程无论如何都要阻塞,它几乎绑定到上下文切换到另一个线程。我同意这是一个有点烦恼,你必须等待(比方说)100ms左右才能确信你的测试会让所有事情都发生在你需要的另一个线程上,但你肯定需要确保它不会上下文切换。

答案 1 :(得分:4)

上下文切换是OS尝试对系统中执行的所有线程\进程“公平”的方法。基于OS,例如Windows,实现基于优先级的抢占式调度。抢占式调度意味着如果更高优先级的线程准备好执行,那么当前线程必须离开CPU。

编写原子代码意味着中断OS调度,操作系统不允许这样做。另外,Windows事件驱动中的调度。除非没有相同\更高优先级的等待线程,否则无法保持CPU。

答案 2 :(得分:2)

Windows和其他所有现代操作系统都是预先安排的多处理操作系统。操作系统负责为各个进程分配时间片,而且各个进程不能占用系统。

想象一下,如果您的代码在魔术“无上下文切换”代码部分中进入无限循环。整个系统将冻结,必须重新启动。

答案 3 :(得分:0)

为什么要坐下来举办活动?难道你不能用(IValueMonitor)的方法来写“获得”你的价值吗?

也许我不明白......