На главную страницу
Форум txt.version   




Статья :: VB.NET Главная опасность (общие данные)

 

Главная опасность (общие данные)

До настоящего момента рассматривался единственный безопасный случай использования потоков - наши потоки не изменяли общих данных. Если разрешить изменение общих данных, потенциальные ошибки начинают плодиться в геометрической прогрессии и избавить от них программу становится гораздо труднее. С другой стороны, если запретить модификацию общих данных разными потоками, многопоточное программирование .NET практически не будет отличаться от ограниченных возможностей VB6.

Вашему вниманию предлагается небольшая программа, которая демонстрирует возникающие проблемы, не углубляясь в излишние подробности. В этой программе моделируется дом, в каждой комнате которого установлен термостат. Если температура на 5 и более градусов по Фаренгейту (около 2,77 градусов по Цельсию) меньше положенной, мы приказываем системе отопления повысить температуру на 5 градусов; в противном случае температура повышается только на 1 градус. Если текущая температура больше либо равна заданной, изменение не производится. Регулировка температуры в каждой комнате осуществляется отдельным потоком с 200-миллисекундной задержкой. Основная работа выполняется следующим фрагментом:

If mHouse.HouseTemp < mHouse.MAX_TEMP = 5 Then Try

Thread.Sleep(200)

Catch tie As ThreadlnterruptedException

' Пассивное ожидание было прервано

Catch e As Exception

' Другие исключения End Try

mHouse.HouseTemp +- 5 ' И т.д.

Ниже приведен полный исходный текст программы. Результат показан на рис. 10.6: температура в доме достигла 105 градусов по Фаренгейту (40,5 градуса по Цельсию)!

1 Option Strict On

2 Imports System.Threading

3 Module Modulel

4 Sub Main()

5 Dim myHouse As New House(l0)

6 Console. ReadLine()

7 End Sub

8 End Module

9 Public Class House

10 Public Const MAX_TEMP As Integer = 75

11 Private mCurTemp As Integer = 55

12 Private mRooms() As Room

13 Public Sub New(ByVal numOfRooms As Integer)

14 ReDim mRooms(numOfRooms = 1)

15 Dim i As Integer

16 Dim aThreadStart As Threading.ThreadStart

17 Dim aThread As Thread

18 For i = 0 To numOfRooms -1

19 Try

20 mRooms(i)=NewRoom(Me, mCurTemp,CStr(i) &"throom")

21 aThreadStart - New ThreadStart(AddressOf _

mRooms(i).CheckTempInRoom)

22 aThread =New Thread(aThreadStart)

23 aThread.Start()

24 Catch E As Exception

25 Console.WriteLine(E.StackTrace)

26 End Try

27 Next

28 End Sub

29 Public Property HouseTemp()As Integer

30 . Get

31 Return mCurTemp

32 End Get

33 Set(ByVal Value As Integer)

34 mCurTemp = Value 35 End Set

36 End Property

37 End Class

38 Public Class Room

39 Private mCurTemp As Integer

40 Private mName As String

41 Private mHouse As House

42 Public Sub New(ByVal theHouse As House,

ByVal temp As Integer, ByVal roomName As String)

43 mHouse = theHouse

44 mCurTemp = temp

45 mName = roomName

46 End Sub

47 Public Sub CheckTempInRoom()

48 ChangeTemperature()

49 End Sub

50 Private Sub ChangeTemperature()

51 Try

52 If mHouse.HouseTemp < mHouse.MAX_TEMP - 5 Then

53 Thread.Sleep(200)

54 mHouse.HouseTemp +- 5

55 Console.WriteLine("Am in " & Me.mName & _

56 ".Current temperature is "&mHouse.HouseTemp)

57 . Elself mHouse.HouseTemp < mHouse.MAX_TEMP Then

58 Thread.Sleep(200)

59 mHouse.HouseTemp += 1

60 Console.WriteLine("Am in " & Me.mName & _

61 ".Current temperature is " & mHouse.HouseTemp)

62 Else

63 Console.WriteLine("Am in " & Me.mName & _

64 ".Current temperature is " & mHouse.HouseTemp)

65 ' Ничего не делать, температура нормальная

66 End If

67 Catch tae As ThreadlnterruptedException

68 ' Пассивное ожидание было прервано

69 Catch e As Exception

70 ' Другие исключения

71 End Try

72 End Sub

73 End Class

Рис. 10.6. Проблемы многопоточности

В процедуре Sub Main (строки 4-7) создается «дом» с десятью «комнатами». Класс House устанавливает максимальную температуру 75 градусов по Фаренгейту (около 24 градусов по Цельсию). В строках 13-28 определяется довольно сложный конструктор дома. Ключевыми для понимания программы являются строки 18-27. Строка 20 создает очередной объект комнаты, при этом конструктору передается ссылка на объект дома, чтобы объект комнаты при необходимости мог к нему обратиться. Строки 21-23 запускают десять потоков для регулировки температуры в каждой комнате. Класс Room определяется в строках 38-73. Ссылка на объект House coxpaняется в переменной mHouse в конструкторе класса Room (строка 43). Код проверки и регулировки температуры (строки 50-66) выглядит просто и естественно, но как вы вскоре убедитесь, это впечатление обманчиво! Обратите внимание на то, что этот код заключен в блок Try-Catch, поскольку в программе используется метод Sleep.

Вряд ли кто-нибудь согласится жить при температуре в 105 градусов по Фаренгейту (40,5 24 градусов по Цельсию). Что же произошло? Проблема связана со следующей строкой:

If mHouse.HouseTemp < mHouse.MAX_TEMP - 5 Then

А происходит следующее: сначала температуру проверяет поток 1. Он видит, что температура слишком низка, и поднимает ее на 5 градусов. К сожалению, перед повышением температуры поток 1 прерывается и управление передаётся поток 2. Поток 2 проверяет ту же самую переменную, которая еще не была изменена потоком 1. Таким образом, поток 2 тоже готовится поднять температуру на 5 градусов, но сделать этого не успевает и тоже переходит в состояние ожидания. Процесс продолжается до тех пор, пока поток 1 не активизируется и не перейдет к следующей команде - повышению температуры на 5 градусов. Повышение повторяется при активизации всех 10 потоков, и жильцам дома придется плохо.

 

VB.NET Главная опасность (общие данные)

страницы в данном разделе 
 VB.NET Многопоточные приложения  VB.NET Знакомство с многопоточностью
 VB.NET Создание потоков  VB.NET Метод Join
 VB.NET Приостановка и уничтожение потоков  VB.NET Главная опасность (общие данные)
 VB.NET Решение проблемы: синхронизация  VB.NET Взаимная блокировка
 VB.NET Совместная работа с данными по мере их создания  VB.NET Многопоточность в графических программах
 VB.NET Следующий шаг: кнопка Show Count  VB.NET Глава 10. Многопоточные приложения


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста