Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.17 Mб
Скачать

11.4.4. Четвертый этап. Удаление ресурса

В отладке этой программы создавалось разное количество грузовиков, их

движение приостанавливолось и возобновлялось, грузовики удалялись и до-

бавлялись. И возникли неприятные ситуации, когда удаляемые грузовики не

удалялись, и при этом появлялось аварийное завершение программы. Как

правило, грузовики не удалялись при нажатии на кнопку "Del", когда они пе-

ред этим приостанавливались кнопкой "Stop" или находились в приостанов-

ленном состоянии в области контроля. В программе что-то не хватало в па-

раллельном взаимодействии потоков грузовиков. В частности, когда приос-

тановившиеся грузовики пытались захватить ресурс и выполнить функцию

Work().

Применение параллельно выполняющихся потоков и, в особенности,

применение при этом потоков, использующих разделяемые ресурсы, требует

тщательного анализа их совместной работы. Здесь возможны дедлоки (deadlock)

- ^пиковые или безысходные ситуации, когда один поток захватил

один ресурс и не может выполняться, поскольку ему нужен ресурс, захва-

ченный вторым потоком, а второй поток не может выполняться, поскольку

ему нужен ресурс, захваченный первым потоком. И эти потоки никогда не

дождутся освобождения ресурсов - программа встанет

Чтобы исключить такую ситуацию, прежде всего, необходимо придержи-

ваться правила, чтобы каждый поток освобождал pecyp тотчас, как он ему

более не нужен. Желательно, чтобы перед захватом ресурса поток проверил,

свободин ли он? И если ресурс занят, то поток начал бы выполнять другую

нужную работу, а позднее ещё сделал бы попьггку завладения этим ресурсом.

Грубейшей ошибкой является удаление объекта, не освободившего исполь-

зуемые им ресурсы.

В нашей программе удалялись (уничтожались) объекты грузовиков, не

освободившие используемый ими ресурс region. После выбора номера грузо-

вика и нажатия на кнопку "Del", выполняется обработчик But_DeI(), который

прекращает поток, вызвав функцию Finish(). Но поток-то может стоять в оче-

реди к ресурсу! Положение усугубляется, когда все грузовики остановлены

нажатием кнопки "Stop" и после этого они удаляются выбором номера грузо-

вика и нажатием на кнопку "Del". Грузовики вне области контроля обычно

удаляются успешно. Но грузовики, захватившие ресурс и посему приоста-

новленные дважды (их потоки приостановлены, поскольку они в очереди к

ресурсу, и еще приостановлены выполнением функции Stop()) не удаляются,

при этом возникает аварийная ситуация. Если грузовик приостановлен, то

вызов функции Stop() для прекращения потока неразумен, так как стоящий в

очереди грузовик продолжит стоять, посколько функция Finish() присвоила

переменной life значение false, и поток не возобновится для выполнения

функции Exit() монитора, освобождающей ресурс. Значит для прекращения

выполнения потока надлежит запустить грузовик и вызвать функцию

Finish(), а до вызова этой функции освободить ресурс.

В примере 11.4.3.2 приведён модифицированный класс Lorry с функци-

ей Dispose(), осуществляющей освобождение ресурса..

Пример 11.4.3.2. Класс Lorry с функцией DisposeO.

///////////////

// C# File csLorry класс Lorry

using System;

using System.Threading;

using System.Drawing;

using System.Windows.Forms;

using csWarehouseDII;

using csContrlRegionDll;

namespace csLorryDII

{

// Класс грузовика

public class Lorry

{