Я стресс-тестировал приведенный ниже код, и он, кажется, работает нормально - каковы опасности не блокирования в простом случае, когда запись одного потока выполняется, а отдельный поток читает простую переменную?
Есть класс, который имеет публичную собственность ...
Public Class PropHolder
Private _myVar As Double
Public Property myVar() As Double
Get
Return _myVar
End Get
Set(ByVal value As Double)
_myVar = value
End Set
End Property
End Class
... и другой, который использует экземпляр этого класса
Public Class Form1
Public _propHolder As New PropHolder
Delegate Sub dlgPostVar()
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While Not BackgroundWorker1.CancellationPending
_propHolder.myVar = someValue 'worker thread writing var
End While
End Sub
Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
While Not BackgroundWorker2.CancellationPending
Me.Invoke(New dlgPostVar(AddressOf postVal)) 'invoke UI thread to write var
End While
End Sub
Private Sub postVal()
RichTextBox1.AppendText(_propHolder.myVar.ToString & vbCrLf)
End Sub
End Class
В приведенном выше примере myVar непрерывно меняется и записывается в RichTextBox так быстро, как может поддерживать UI. Не все значения фиксируются, но это не важно - давайте представим, что RichTextBox заботится только о выборке текущего значения myVar в свободное время.
Все, что я прочитал, наводит меня на мысль, что это небезопасно, но мне еще предстоит сделать его неудачным, даже когда две переменные читают и пишут (один читатель, один писатель) эту переменную непрерывно. Что может пойти не так и почему?
Редактировать: Чтобы быть более конкретным, этот вопрос скорее гипотетический, чем практический. Я знаю, что эта ситуация требует блокировки «по книге», вопрос состоит в том, чтобы исследовать широту потенциальных последствий отсутствия блокировки в этом случае, возможно, в виде полного набора всех возможных способов отказа.
Одним из примеров, таким образом, является чтение из переменной, записываемой в:
- Тема 1 -> Читает младшее слово из памяти
- Thread 2 -> CPU перемещает младшее слово нового значения в память
- Thread 2 -> CPU перемещает старшее слово нового значения в память
- Тема 1 -> Читает старшее слово из памяти
Значение потока 1 теперь (HighWord [новое]) (LowWord [старое]) ** повреждено
Ошибка программы ограничена повреждением, вызванным обработкой этого поврежденного значения.
Другие последствия этого режима отказа? Есть ли?
Дополнительные примеры? Книги / ссылки приветствуются.
Редактировать # 2: Мое намерение здесь состоит в том, чтобы исследовать в среде .NET степень и форму непредсказуемости и ошибок, которые свойственны платформе и конкретно не связаны с последствиями того, как любая конкретная программа может впоследствии потерпеть неудачу. лицо такой ошибки.
В приведенном выше примере я ничего не делаю со значением, кроме записи его в виде текста. Если я получаю неверное значение, я записываю неверное значение в текст - ничего не взрывается, программа не падает, империи не падают, а орбита Меркурия остается стабильной.