Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Межпроцессорное взаимодействие и многопоточность в .NET (реферат).docx
Скачиваний:
30
Добавлен:
28.06.2014
Размер:
139.35 Кб
Скачать

Класс Semaphore

Общая информация.

Описание:

Фиксирует число потоков которые могут обращаться к ресурсам одновременно. (Более подробную информацию можно найти в [8])

Иерархия:

System.Object    System.MarshalByRefObject      System.Threading.WaitHandle       System.Threading.Semaphore

Определение:

[C#]

[ComVisibleAttribute(false)]

public sealed class Semaphore : WaitHandle

Потокобезопасность:

Этот тип можно использовать в многопоточных операциях.

Semaphore – составляющие

Свойства

 

Name

Description

Handle 

Получает или устанавливает низкоуровневый handle операционной систем

Методы

 

Name

Description

Close 

Освобождает все ресурсы использованные WaitHandle

GetAccessControl

Позволяет получить безопасный доступ к именнованому объекту семафор

OpenExisting

Открывает существующий именнованный семафор

Release

Выход из семафора

SetAccessControl

Устанавливает доступ к именнованому объекту семафор

SignalAndWait 

Сигнализирует одному WaitHandle и ждет другого

WaitAll 

Ждет все элементы в специальном массиве для приема сигнала

WaitAny 

Ждет какой-либо элемент в специальном массиве для приема сигнала

WaitOne 

Блокирует текущий поток до тех пор текущий WaitSignal не получит сигнал.

Примеры:

  1. Демонстрация использования метода WaitAny класса Semaphore. Пример является фрагментом более объемной программы

static void Main()

{

//Очередь двух задач в двух различных потоках

//Ждем завершения обеих задач

DateTime dt = DateTime.Now;

Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");

ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);

ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);

WaitHandle.WaitAll(waitHandles);

// Время от более долгой задачи

//Вывод на консоль

Console.WriteLine("Both tasks are completed (time waited={0})",

(DateTime.Now - dt).TotalMilliseconds);

//Очередь двух задач в двух различных потоках

//Ждем завершения какой-либо из задач

dt = DateTime.Now;

Console.WriteLine();

Console.WriteLine("The main thread is waiting for either task to complete.");

ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);

ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);

int index = WaitHandle.WaitAny(waitHandles);

// Время от наикротчайшей задачи

//Вывод на консоль

Console.WriteLine("Task {0} finished first (time waited={1}).",

index + 1, (DateTime.Now - dt).TotalMilliseconds);

}

  1. Пример демонстрирующий использования класса Semaphore

using System;

using System.Threading;

public class Example

{

//Демонстрация доступа к пулу ресурсов

private static Semaphore _pool;

//Интервал для более последовательного вывода на консоль

private static int _padding;

public static void Main()

{

//Создаем семафор который может разрешить

//до трех конкурирующих задач. Использование

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

//главном(main) потоке программы

_pool = new Semaphore(0, 3);

//Создаем и запускаем пять потокав

for (int i = 1; i <= 5; i++)

{

Thread t = new Thread(new ParameterizedThreadStart(Worker));

//Запускаем поток соответствующий номеру

t.Start(i);

}

//Ждем пол-секунды, чтобы позваолить потокам запуститься

//и быть заблокироваными семафором

Thread.Sleep(500);

Console.WriteLine("Main thread calls Release(3).");

//Позволяем ожидающим потокам стартовать через

// семафор, до трех раз

_pool.Release(3);

//Выход из главного потока

Console.WriteLine("Main thread exits.");

}

private static void Worker(object num)

{

//Каждый рабочий поток запускаеться по запросу

//семафора

Console.WriteLine("Thread {0} begins " +

"and waits for the semaphore.", num);

_pool.WaitOne();

// Интервал для более последовательного вывода на консоль

int padding = Interlocked.Add(ref _padding, 100);

Console.WriteLine("Thread {0} enters the semaphore.", num);

//Работа каждого из потоков – спать секунду

// и немного еще для наглядного вывода на консоль

Thread.Sleep(1000 + padding);

//Вывод на консоль

Console.WriteLine("Thread {0} releases the semaphore.", num);

Console.WriteLine("Thread {0} previous semaphore count: {1}",

num, _pool.Release());

}

}