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

If (I moving)

Monitor.Wait (this); // Ожидать разблокировки

Console.WriteLine(" n= " + n++);

>

Console.WriteLine ("Thread finished");

>

>

class SuspendResume

{

static void Main ( )

<

User us= new User ( ); // Создать объект с

// выполняющимся потоком

Console.WriteLine ("Поток стартовал");

Thread.Sleep (70);

us.SuspendUser( ); // Приостановить поток

Console.WriteLine ("Поток приостановлен");

Thread.Sleep (70);

us.ResumeUser ( ); // Возобновить поток

Console.WriteLine ("Поток возобновлён");

Thread.Sleep (70);

>

/>*

Result:

Поток стартовал

n= 1

n= 2

n= 3

n= 4

Поток приостановлен

Поток возобновлён

n= 5

n= 6

n= 7

n= 8

n= 9

Thread finished

*/

Программа примера 9.6.2.2.2 на языке C# аналогична программе примера

9.6.2.1.1 Наязыке Java, отличаясьтолько применением функций монитора

Monitor и созданием синхронизированного блока с помощью synchronized.

Результат работы программ совпадает (отличие возможно только из-за раз-

ной производительности процессора).

9.6.2.3. Использование монитора в C++/CLI

Ограничимся рассмотрением монитора для приостановки и возобнов-

ления потока, чтобы, воспользовавшись этим, исключить в дальнейшем ис-

пользование запрещённых функций Suspend() и Resume() класса Thread на

языке. C++/CLI. Пример 9.6.2.3 программы на языке C++/CLI аналогичен

примеру 9.6.2.2.2 программы на языке C#.

Части программы, связанные с синхронизацией выполнения потока,

необходимо представить в виде синхронизированных блоков. То есть сфор-

мировать их в виде критических секций, начинающихся вызовом функции

Enter() монитора и завершающихся вызовом функции Exit(). Поскольку в

программе примера 9.6.2.3.2 приостанавливается и возобновляется выполне-

ние потока объекта, которому принадлежит поток, то аргумент функций Enter()

и Exit(), ссылающийся на объект, должен быть равен this.

Пример 9.6.2.3.2. Приостановка и возобновление потока в C++/CLI

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

// C++/CLI

#include "stdafX.h"

#using <System.Drawing.dll>

#using <System.Windows.Forms.dll>

using namespace System;

using namespace System::Windows::Forms;

using namespace System::Drawlng;

using namespace System::Threading;

ref class User // Класс объектов с потоками

User (int Num)

<

num= Num;

n= 0;

moving= true;

// Создать и стартовать поток

thr= gcnewThread (gcnew ThreadStart(this, &User::ThrFunc));

thr->Start ();

{

int num;

int n;

Thread ^thr;

bool movlng;

// Номер объекта

// Порядковый номер цикла потока

// Ссылка на поток

// Признак выполнения потока

public:

>

void SuspendUser ( ) // Приостановить поток

{

moving= false;

void ResumeUser ( ) // Возобновить поток

{

Monitor::Enter (thls); // Создать синхронизируемый блок

moving= true;

Monltor::Pulse (this); // Разблокировать поток

Monitor::Exit (this); // Завершить синхронизируемый блок

>

private:

// Потоковая функция

void ThrFunc ( )

{

while (n < 10)

{

Thread::Sleep (10);

Monitor::Enter (this); // Создать синхронизируемый блок

if (I moving)

Monitor::Wait (this); // Ожидать разблокировки

Monitor::Exit (this); // Завершить синхронизируемый блок

n++;

Console::WrlteLlne("num= {0> n= {1}", num, n);

>

Console::WriteLine ("Thread num= {0> finished", num);

>

>;

void main ( )

{

User ^usl = gcnew User (1); // Создать первый объект с потоком

User ^us2= gcnew User (2); // Создать второй объект с потоком

Console::WriteLine ("Потоки стартовали");

Thread::Sleep (40);

usl->SuspendUser ( ); // Приостановить поток первого объекта

Console::WriteLine ("Поток первого объекта приостановлен");

Thread::Sleep (40);

usl->ResumeUser ( ); // Возобновить поток первого объекта

Console::WriteLine ("Поток первого объекта возобновлён");

>

/*Result:

num=l n=l

num=2 n=l

num=l n=2

num=2 n=2

Поток первого объекта приостановлен

num=2 n=3

num=2 n=4

Поток первого объекта возобновлён

num=l n=3

num=2 n=5

Thread num= 2 finished

num=l n=4

num=l n=5

Thread num= 1 finished

*/

Класс User потокового объекта для управления выполнения потоком

включает логическую переменную moving. При создании потокового объекта

конструктор присваивает переменной moving значение true, создаёт поток с

потоковой функцией ThrFunc() и стартует его. Истинное значение перемен-

ной moving не требует разблокировки выполняющегося потока.

Выполнение интерфейсной функции SuspendUser() присвоит

переменной moving значение false, чте приводит к вызову функции Ws!t()

монитора в критической секции потоковой функции и, как результат, к

блокировке потока - выполнение потоковой функции ThrFunc()

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

ResumeUser() присвоит переменной moving значение true и вызовет в

критической секции функцию монитора Pulse(). Функция Pulse()

разблокирует поток, и потоколвая функция ThrFunc() продолжит своё

выполнение.