Лабораторная работа №8

Потоки

Создание потока

Для создания потока необходимо создать объект класса Thread.

Один из конструкторов этого класса имеет следующий вид:

public Thread (ThreadStart start)

 

Объект start типа ThreadStart должен содержать адрес точки входа в функцию, которая будет выполняться в потоке.

Тип ThreadStart объявлен в пространстве имен System.Threading с помощью ключевого слова delegate и имеет следующую сигнатуру:

 

public delegate void ThreadStart();

 

Согласно, сигнатуре объявления делегата, потоковая функция должна возвращать значение типа void и не принимать параметров.

Пусть, например, заголовок потоковой функции - void funcThread(), тогда создание объекта start:

 

ThreadStart start = new ThreadStart(funcThread);

 

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

Объект start после своего создания хранит адрес точки входа в функцию funcThread.

Следующим шагом необходимо создать потоковый объект, передав конструктору класса Thread объект start в качестве параметра:

 

Thread thrd = new Thread(start);

 

После создания потокового объекта необходимо запустить потоковую функцию на выполнение путем вызова метода Start, используя ссылку thrd:

 

thrd.Start();

 

Потоковому объекту с помощью свойства Name можно присвоить некоторое имя:

thrd.Name = “ ThrName”;,

или прочесть:

strig nm = thrd.Name;

Поток считается активным, не зависимо от того находится ли он в состоянии останова или нет, до тех пор, пока не завершится запущенная в нем функция. После завершения потоковой функции поток уничтожается. Такое завершение работы потока считается нормальным. Узнать, находиться ли поток в активном состоянии или нет можно с помощью свойства IsAlive, доступного только для чтения. Свойство возвращает значение true, если поток активен и ложь (false), если нет. Это свойство можно использовать для определения момента окончания работы потока. Приостановить работу потока на определенное время можно с помощью статического метода:

public static void Sleep(int time)

класса Thread, где параметр time задает время в миллисекундах.

Для закрепления материала рассмотрим пример, демонстрирующий изложенный материал.

Пример 1:

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

namespace ConsoleApplication4

{

class MyThread

{

private int count; //счетчик

//объявление ссылки на потоковый объект

public Thread thrd;

public MyThread(string name)

{

count = 0;

//здесь создается потоковый объект для функции FnThr

thrd = new Thread(new ThreadStart(this.FnThr));

thrd.Name = name; // Устанавливаем имя потока.

thrd.Start(); // Запускаем поток на выполнение.

}

//определение потоковой функции

public void FnThr()

{

Console.WriteLine(thrd.Name + " стартовал.");

do

{

Thread.Sleep(300); //”засыпаем” на 0,3 сек

Console.WriteLine("В потоке " + thrd.Name + ", count - " + count);

count++;

} while (count <= 4);

Console.WriteLine(thrd.Name + " завершен.");

}

}

class Program

{

static void Main(string[] args)

{

Console.WriteLine("Главный поток стартовал.");

// Создаем массив ссылок на потоковые объекты

MyThread[] mt = new MyThread[5];

// Создаем объекты класса MyThread.

for (int j = 0; j < mt.Length; j++)

mt[j] = new MyThread("Потомок #" + j.ToString());

bool live;

do

{

live=false;

Console.Write(".");

Thread.Sleep(100); //”спит” главный поток

for (int j = 0; j < mt.Length; j++)

{

live = live | mt[j].thrd.IsAlive;

}

 

} while (live);

Console.WriteLine("Главный поток завершен.");

 

}

 

}

}

В этом приложении объявлен класс MyThread. Конструктор класса MyThread создает потоковый объект с помощью строки кода:

 

thrd = new Thread(new ThreadStart(this.FnThr));

 

Затем потоковому объекту присваивается имя, которое конструктор принимает в качестве параметра и запускается с помощью метода Start() поток, что приводит к вызову потокового метода FnThr().

В методе FnThr () организован цикл, который "считает" от 0 до 4. До входа в цикл метод выводит на консоль имя стартовавшего потока, а после окончания цикла – имя завершившего свою работу потока. Вызов метода Sleep(), в теле цикла метода FnThr () заставляет поток, из которого он был вызван, приостановить выполнение на период времени, заданный в миллисекундах. В методе Main() при выполнении следующих инструкций создается пять объектов класса Thread:

 

// Создаем массив ссылок на потоковые объекты

MyThread[] mt = new MyThread[5];

// Создаем объекты класса MyThread.

for (int j = 0; j < mt.Length; j++)

mt[j] = new MyThread("Потомок #" + j.ToString());

 

После создания потоков и запуска их на выполнение в конструкторе класса MyThread, в приложении выполняются основной поток, а, именно, метод Main() и пять дочерних потоков.

С помощью цикла:

 

for (int j = 0; j < mt.Length; j++)

{

live = live | mt[j].thrd.IsAlive;

}

 

} while (live);

 

метод Main() дожидается завершения работы потоков.

 

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: