運行截圖如下
此時,PID 為 4628的進程正在等待PID為 3216的進程釋放configFileMutex的互斥體,因此它阻塞在WaitOne函數中,當PID為3216的進程添加並寫入了一條信息至config.txt文件後,釋放configFileMutex的獨占權,PID為4628的進程獲取configFileMutex的獨占權,並從config.txt文件中讀取輸出PID3216進程寫入的信息,截圖如下
可見使用Mutex進行同步,同步的互斥體是存在於多個進程間的。
6.使用System.Threading.ReaderWriterLock類實現多用戶讀/單用戶寫的同步訪問機制
在考慮資源訪問的時候,慣性上我們會對資源實施lock機制,但是在某些情況下,我們僅僅需要讀取資源的數據,而不是修改資源的數據,在這種情況下獲取資源的獨占權無疑會影響運行效率,因此.Net提供了一種機制,使用ReaderWriterLock進行資源訪問時,如果在某一時刻資源並沒有獲取寫的獨占權,那麼可以獲得多個讀的訪問權,單個寫入的獨占權,如果某一時刻已經獲取了寫入的獨占權,那麼其它讀取的訪問權必須進行等待,參考以下代碼
using System;
using System.Collections.Generic;
using System.Text; using System.Threading;
using System.IO;
using System.Diagnostics;
namespace MonitorApplication
{
class Program
{
private static ReaderWriterLock m_readerWriterLock = new ReaderWriterLock();
private static int m_int = 0;
static void Main(string[] args)
{
Thread readThread = new Thread(Read);
readThread.Name = "ReadThread1";
Thread readThread2 = new Thread(Read);
readThread2.Name = "ReadThread2";
Thread writeThread = new Thread(Writer);
writeThread.Name = "WriterThread";
readThread.Start();
readThread2.Start();
writeThread.Start();
readThread.Join();
readThread2.Join();
writeThread.Join();
}
private static void Read()
{
while (true)
{
Console.WriteLine("ThreadName " + Thread.CurrentThread.Name + " AcquireReaderLock");
m_readerWriterLock.AcquireReaderLock(10000);
Console.WriteLine(String.Format("ThreadName : {0} m_int : {1}", Thread.CurrentThread.Name, m_int));
m_readerWriterLock.ReleaseReaderLock();
}
}
private static void Writer()
{
while (true)
{
Console.WriteLine("ThreadName " + Thread.CurrentThread.Name + " AcquireWriterLock");
m_readerWriterLock.AcquireWriterLock(1000); Interlocked.Increment(ref m_int);
Thread.Sleep(5000);
m_readerWriterLock.ReleaseWriterLock();
Console.WriteLine("ThreadName " + Thread.CurrentThread.Name + " ReleaseWriterLock");
}
}
}
}
在程序中,我們啟動兩個線程獲取m_int的讀取訪問權,使用一個線程獲取m_int的寫入獨占權,執行代碼後,輸出如下
可以看到,當WriterThread獲取到寫入獨占權後,任何其它讀取的線程都必須等待,直到WriterThread釋放掉寫入獨占權後,才能獲取到數據的訪問權, 應該注意的是,上述打印信息很明顯顯示出,可以多個線程同時獲取數據的讀取權,這從ReadThread1和ReadThread2的信息交互輸出可以看出。