Tải bản đầy đủ - 0 (trang)
4-9. Synchronize the Execution of Multiple Threads Using a Mutex

4-9. Synchronize the Execution of Multiple Threads Using a Mutex

Tải bản đầy đủ - 0trang

CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



// Boolean to signal that the second thread should terminate.

static bool terminate = false;

// A utility method for displaying useful trace information to the

// console along with details of the current thread.

private static void TraceMsg(string msg)

{

Console.WriteLine("[{0,3}] - {1} : {2}",

Thread.CurrentThread.ManagedThreadId,

DateTime.Now.ToString("HH:mm:ss.ffff"), msg);

}

// Declare the method that will be executed on the separate thread.

// In a loop the method waits to obtain a Mutex before displaying a

// message to the console and then waits 1 second before releasing the

// Mutex.

private static void DisplayMessage()

{

// Obtain a handle to the Mutex with the name "MutexExample".

// Do not attempt to take ownership immediately.

using (Mutex mutex = new Mutex(false, "MutexExample"))

{

TraceMsg("Thread started.");

while (!terminate)

{

// Wait on the Mutex.

mutex.WaitOne();

TraceMsg("Thread owns the Mutex.");

Thread.Sleep(1000);

TraceMsg("Thread releasing the Mutex.");

// Release the Mutex.

mutex.ReleaseMutex();

// Sleep a little to give another thread a good chance of

// acquiring the Mutex.

Thread.Sleep(100);

}

TraceMsg("Thread terminating.");

}

}



183



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



public static void Main()

{

// Create a new Mutex with the name "MutexExample".

using (Mutex mutex = new Mutex(false, "MutexExample"))

{

TraceMsg("Starting threads -- press Enter to terminate.");

// Create and start three new threads running the

// DisplayMesssage method.

Thread trd1 = new Thread(DisplayMessage);

Thread trd2 = new Thread(DisplayMessage);

Thread trd3 = new Thread(DisplayMessage);

trd1.Start();

trd2.Start();

trd3.Start();

// Wait for Enter to be pressed.

Console.ReadLine();

// Terminate the DisplayMessage threads, and wait for them to

// complete before disposing of the Mutex.

terminate = true;

trd1.Join(5000);

trd2.Join(5000);

trd3.Join(5000);

}

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



■ Note Recipe 4-17 demonstrates how to use a named Mutex as a means to ensure that only a single instance of

an application can be started at any given time.



184



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



4-10. Synchronize the Execution of Multiple Threads Using a

Semaphore

Problem

You need to control the number of threads that can access a shared resource or section of code

concurrently.



Solution

Use the System.Threading.Semaphore class.



How It Works

The Semaphore is another synchronization class derived from the System.Threading.WaitHandle class and

will be familiar to those with Win32 programming experience. The purpose of the Semaphore is to allow a

specified maximum number of threads to access a shared resource or section of code concurrently.

As with the other synchronization classes derived from WaitHandle (discussed in recipe 4-8 and

recipe 4-9), a Semaphore is either in a signaled state or an unsignaled state. Threads wait for the Semaphore

to become signaled using the methods described in Table 4-1. The Semaphore maintains a count of the

active threads it has allowed through and automatically switches to an unsignaled state once the

maximum number of threads is reached. To release the Semaphore and allow other waiting threads the

opportunity to act, a thread calls the Release method on the Semaphore object. A thread may acquire

ownership of the Semaphore more than once, reducing the maximum number of threads that can be

active concurrently, and must call Release the same number of times to fully release it.



The Code

The following example demonstrates how to use a named Semaphore to limit access to a shared resource

(the console) to two threads at any given time. The code is similar to that used in recipe 4-9 but

substitutes a Semaphore for the Mutex.

using System;

using System.Threading;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_10

{

// Boolean to signal that the second thread should terminate.

static bool terminate = false;



185



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



// A utility method for displaying useful trace information to the

// console along with details of the current thread.

private static void TraceMsg(string msg)

{

Console.WriteLine("[{0,3}] - {1} : {2}",

Thread.CurrentThread.ManagedThreadId,

DateTime.Now.ToString("HH:mm:ss.ffff"), msg);

}

// Declare the method that will be executed on the separate thread.

// In a loop the method waits to obtain a Semaphore before displaying a

// message to the console and then waits 1 second before releasing the

// Semaphore.

private static void DisplayMessage()

{

// Obtain a handle to the Semaphore with the name "SemaphoreExample".

using (Semaphore sem = Semaphore.OpenExisting("SemaphoreExample"))

{

TraceMsg("Thread started.");

while (!terminate)

{

// Wait on the Semaphore.

sem.WaitOne();

TraceMsg("Thread owns the Semaphore.");

Thread.Sleep(1000);

TraceMsg("Thread releasing the Semaphore.");

// Release the Semaphore.

sem.Release();

// Sleep a little to give another thread a good chance of

// acquiring the Semaphore.

Thread.Sleep(100);

}

TraceMsg("Thread terminating.");

}

}

public static void Main()

{

// Create a new Semaphore with the name "SemaphoreExample". The

// Semaphore can be owned by up to two threads at the same time.

using (Semaphore sem = new Semaphore(2,2,"SemaphoreExample"))

{

TraceMsg("Starting threads -- press Enter to terminate.");



186



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

4-9. Synchronize the Execution of Multiple Threads Using a Mutex

Tải bản đầy đủ ngay(0 tr)

×