Есть ли способ принудительного выполнения атомарной операции без переключения контекста в C #? - PullRequest
0 голосов
/ 20 апреля 2009

У меня есть несколько строк метода, которые я хотел бы гарантировать, что при выполнении этих команд не происходит переключения контекста на другой поток? Да, реструктуризация - это вариант, но сейчас было бы гораздо целесообразнее, если бы я мог это сделать.

Возможно ли это? Если нет, то знает ли кто-нибудь причину решения?

Редактировать: Причина, по которой я спрашиваю, состоит в том, что у меня есть класс, отвечающий за возвращение значения, значение предоставляется через событие, поэтому при вызове 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 ]

9 голосов
/ 20 апреля 2009

Нет, вы не можете. Вы можете использовать блокировку, чтобы убедиться, что никакие другие потоки не будут вводить конфиденциальные фрагменты кода, связанные с вашей работой, но это все.

Что касается «почему» - это обычно не нужно, и было бы немного странно в упреждающей операционной системе на платформе относительно высокого уровня. Это может быть возможно в коде драйвера, но обычно это не требуется в коде пользователя.

Обратите внимание, что «выполнение других потоков» не обязательно означает переключение контекста в любом случае, учитывая многоядерные и многопроцессорные машины.

РЕДАКТИРОВАТЬ: Несмотря на ваше редактирование, я до сих пор не понимаю, почему проблема заключается в переключении контекста. Если поток все равно должен блокироваться, он в значительной степени связан с переключением контекста на другой поток. Я согласен, что немного раздражает, что вам приходится ждать (скажем) 100 мс или около того, чтобы быть уверенным, что ваш тест позволит всему происходить в другом потоке, который вам нужен, но вам определенно не нужно чтобы не переключать контекст.

4 голосов
/ 20 апреля 2009

Переключение контекста - это метод, с помощью которого ОС пытается быть «справедливой» для всех потоков \ процессов, выполняемых в системе. На основе ОС, например Windows, реализуется приоритетное планирование на основе приоритетов. Упреждающее планирование означает, что если поток с более высоким приоритетом готов к выполнению, то текущий поток должен покинуть ЦП.

Написание атомарного кода означает прерывание планирования ОС, которое ОС не позволяет. Кроме того, планирование в Windows, управляемое событиями. Вы не можете удерживать процессор, если нет ожидающих потоков с тем же \ более высоким приоритетом.

2 голосов
/ 20 апреля 2009

Windows и любая другая современная ОС - это многопроцессорная ОС с вытеснением по расписанию. ОС отвечает за распределение временных интервалов для отдельных процессов, и отдельные процессы не могут перегружать систему.

Представьте, что ваш код вошел в бесконечный цикл внутри вашего магического раздела кода "без переключения контекста". Вся система зависнет и должна быть перезагружена.

0 голосов
/ 23 апреля 2009

Зачем сидеть на мероприятии, чтобы запустить? Разве вы не можете написать в методе (IValueMonitor), чтобы "получить" ваше значение?

Возможно, я не понимаю ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...