:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Головна небезпека (загальні дані)

    До справжнього моменту розглядався єдиний безпечний випадок використання потоків — наші потоки не змінювали загальних даних. Якщо вирішити зміну загальних даних, потенційні помилки починають плодитися в геометричній прогресії і позбавити від них програму стає набагато важчим. З іншого боку, якщо заборонити модифікацію загальних даних різними потоками, багатопотокове програмування .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 зберігається в змінній 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 потоків, і мешканцям будинку доведеться погано.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©