<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">互斥:是指某一資源同時隻允許一個通路者對其進行通路,具有唯一性和排它性。但互斥無法限制通路者對資源的通路順序,即通路是無序的。</span>
同步:是指在互斥的基礎上(大多數情況),通過其它機制實作通路者對資源的有序通路。在大多數情況下,同步已經實作了互斥,特别是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個通路者同時通路資源,如“第一類讀寫者模型”。
通過以下題目來說明互斥與同步:
程式描述:
主線程啟動10個子線程并将表示子線程式号的變量位址作為參數傳遞給子線程。子線程接收參數 ->sleep(50) -> 全局變量++ ->sleep(0) -> 輸出參數和全局變量。
要求:
1.子線程輸出的線程式号不能重複。
2.全局變量的輸出必須遞增。
分析:
1.主線程建立子線程并傳入一個指向變量位址的指針作參數,由于線程啟動須要花費一定的時間,是以在子線程根據這個指針通路并儲存資料前,主線程應等待子線程儲存完畢後才能改動該參數并啟動下一個線程。這涉及到主線程與子線程之間的同步。
2.子線程之間會互斥的改動和輸出全局變量。要求全局變量的輸出必須遞增。這涉及到各子線程間的互斥。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace SyncAndMutex
{
class Program
{
static int mResource =0;
static int threadcount = 10;
static ManualResetEvent resetevent = new ManualResetEvent(false);
static Object mCriticalSectionObj = new Object();
static void Main(string[] args)
{
Pointer pt = new Pointer(0);
for (int i = 0; i < threadcount; ++i)
{
Thread td = new Thread(ThreadTask);
pt.PointValue = i;
td.Start(pt);
resetevent.WaitOne();
resetevent.Reset();// if use the autoresetevent,it's unnecesary to call the reset()
}
}
static void ThreadTask(object threadorderid)
{
int id = ((Pointer)threadorderid).PointValue;//copy the value
resetevent.Set();
Monitor.Enter(mCriticalSectionObj);
Thread.Sleep(50);
mResource += 1;
Thread.Sleep(0);
Console.WriteLine("The Thread Order ID is " + id + " The Resource is " + mResource);
Monitor.Exit(mCriticalSectionObj);
}
}
class Pointer
{
public Pointer(int pointervalue)
{
mv = pointervalue;
}
int mv = -1;
public int PointValue
{
get { return mv; }
set { mv = value; }
}
}
}
在代碼中,為了展現出同步,是以專門建構class Pointer 作為參數,注意在此,如果将Int 型的i直接作為實參,那麼每次實參到形參object都會重新構造對象,這樣對于每一個子線程啟動線程函數,使用每一份object都是新的獨立的,進而将不需要同步操作。
參考:
http://blog.csdn.net/morewindows/article/details/7442333
http://blog.csdn.net/MoreWindows/article/details/7442639
http://blog.csdn.net/MoreWindows/article/details/7470936