|
|||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||
|
Знайомство
з багатопоточністю
Кожна програма
працює в певному контексті, що
описує розподіл коди і
даних в пам'яті. При збереженні
контексту фактично зберігається
стан програмного потоку, що
дозволяє в майбутньому відновити
його і продовжити виконання
програми. Збереження
контексту зв'язане з
певними витратами часу і
пам'яті. Операційна система
запам'ятовує стан програмного
потоку і передає управління
іншому потоку. Коли програма
захоче продовжити виконання
припиненого потоку,
збережений контекст доводиться
відновлювати, на що йде ще
більше часу. Отже,
багатопоточність слід
використовувати лише в тих випадках,
коли переваги компенсують
всі витрати. Нижче перераховані
деякі типові приклади.
Перш ніж переходити
до механіки роботи багатопотокових
програм, необхідно вказати
на одну обставину, що
часто викликає непорозуміння у
новачків в області багатопотокового
програмування. У програмному
потоці виконаються процедура, а не
об'єкт. Важко сказати, що слід розуміти під
виразом «виконується об'єкт», але
один з авторів
часто веде семінари з багатопотокового програмування
і це питання
задають частіше за інших.
Можливо, хтось вважає, що робота
програмного потоку починається з
виклику методу New класу, після
чого потік обробляє всі повідомлення,
передавані відповідному об'єкту.
Такі уявлення
абсолютно невірні. Один об'єкт
може містити декілька потоків,
що виконують різні
(а іноді навіть однакові) методи,
при цьому повідомлення об'єкту
передаються і приймаються декількома
різними потоками (до
речі, це одна з причин, що
утрудняють багатопотокове
програмування: щоб відладити
програму, необхідно дізнатися, який
потік в даний момент виконує ту
або іншу процедуру!). Оскільки програмні
потоки створюються на базі
методів об'єктів, сам об'єкт зазвичай
створюється раніше потоку. Після
успішного створення об'єкту програма
створює потік, передаючи йому
адресу методу об'єкту, і лише після
цього віддає розпорядження про
початок виконання потоку. Процедура,
для якої створювався потік,
як і всі процедури, може створювати
нові об'єкти, виконувати операції
з існуючими об'єктами і
викликати інші процедури і функції,
що знаходяться в її зоні
видимості.
Основні засоби
.NET, що відносяться до
використання програмних потоків,
зосереджені в просторі імен
Threading. Отже, більшість
багатопотокових програм повинна
починатися з наступного рядка: Imports System.Threading Імпортування
простору імен спрощує введення
програми і дозволяє використовувати
технологію Intellisense. Безпосередній зв'язок потоків з процедурами наводить на припущення про те, що в цій картині важливе місце займають делегати (див. розділ 6). Зокрема, в простір імен Threading входить делегат Threadstart, зазвичай використовуваний при запуску програмних потоків. Синтаксис використання цього делегата виглядає так: Public Delegate Sub
Threadstart() Код, що викликається за
допомогою делегата Threadstart, не повинен
мати параметрів і повертаного
значення, тому потоки
не можуть створюватися для функцій
(які повертають значення)
і для процедур з параметрами.
Для передачі інформації
з потоку теж доводиться
шукати альтернативні засоби,
оскільки виконувані методи
не повертають значень і не можуть
використовувати передачу по посиланню.
Наприклад, якщо процедура Threadmethod
знаходиться в класі Willusethread, то
Threadmethod може передавати інформацію
за допомогою зміни
властивостей екземплярів класу Willusethread.
Програмні
потоки .NET працюють в так званих
доменах додатків, визначуваних в
документації як «ізольоване
середовище, в якому виконується
додаток». Домен додатку
можна розглядати як
полегшений варіант процесів Win32;
один процес Win32 може містити
декілька доменів додатків.
Головна відмінність між доменами
додатків і процесами
полягає в тому, що процес Win32
володіє самостійним адресним
простором (у документації
домени додатків також
порівнюються з логічними
процесами, що працюють
усередині фізичного процесу). У .NET
все управління пам'яттю
здійснюється виконавчим середовищем, тому
в одному процесі Win32 можуть
працювати декілька доменів
додатків. Однією з переваг цієї
схеми є поліпшення
можливостей масштабування (scaling)
додатків. Засоби для роботи з
доменами додатків знаходяться в класі
Appdomain. Рекомендуємо вивчити
документацію по цьому класу. З його допомогою
можна отримати інформацію про оточення,
в якому працює ваша програма.
Зокрема, клас Appdomain застосовується
при виконанні рефлексії для
системних класів .NET. Наступна
програма виводить список
завантажених складок. Imports System.Reflection Module
Modulel Sub Main() Dim
thedomain As Appdomain thedomain =
Appdomain.CurrentDomain Dim Assemblies()As [Assembly
] Assemblies = thedomain.GetAssemblies Dim anassemblyxas [Assembly ] For Each
anassembly In Assemblies Console.WriteLinetanAssembly.Full
Name) Next Console.ReadLine() End Sub End Module
|
|
|||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||