----------------------------------------------文章1----------------------------------------------
互斥鎖(Mutex)
互斥鎖是一個互斥的同步對象,意味着同一時間有且僅有一個線程可以獲取它。
互斥鎖可適用於一個共享資源每次只能被一個線程訪問的情況
函數:
//創建一個處於未獲取狀態的互斥鎖
Public Mutex();
//如果owned為true,互斥鎖的初始狀態就是被主線程所獲取,否則處於未獲取狀態
Public Mutex(bool owned);
如果要獲取一個互斥鎖。應調用互斥鎖上的WaitOne()方法,該方法繼承於Thread.WaitHandle類
它處於等到狀態直至所調用互斥鎖可以被獲取,因此該方法將組織住主調線程直到指定的互斥鎖可用,如果不需要擁有互斥鎖,用ReleaseMutex方法釋放,從而使互斥鎖可以被另外一個線程所獲取
//Public Mutex(bool owned,name,out flag);
name為互斥量的名字,也就是說在操作系統中只有一個命名為name的互斥量mutex,如果一個線程得到這個name的互斥鎖,其他線程就無法得到這個互斥鎖了,必須等待那個線程對這個線程釋放
參考別人的博客的代碼實驗
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace myConApp
{
class Test
{
/// <summary>
/// 應用程序的主入口點。
/// </summary>
[STAThread]
static void Main(string[] args)
{
bool flag = false;
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Test", out flag);
//第一個參數:true--給調用線程賦予互斥體的初始所屬權
//第一個參數:互斥體的名稱
//第三個參數:返回值,如果調用線程已被授予互斥體的初始所屬權,則返回true
if (flag)
{
Console.Write("Running");
}
else
{
Console.Write("Another is Running");
System.Threading.Thread.Sleep(5000);//線程掛起5秒鍾
Environment.Exit(1);//退出程序
}
Console.ReadLine();
}
}
}
運行以上代碼生成的應用程序第一個實例,會得到結果
Running
保持第一個運行狀態,運行第二個實例,得到結果
Another is Running
以上代碼中創建了一個mutex,從其參數的解釋中得知,第一個調用線程將得到互斥體的初始所屬權,如果不釋放的話,其他的線程得不到互斥體所有權
1.運行兩個工程,同時將以上代碼放入工程中,第一個工程運行,得到結果
Running
保持第一個運行狀態,運行第二個工程,得到結果
Another is Running
2.將一個工程中的System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Test", out flag);改為
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Test1", out flag);
然后第一個工程運行,得到結果
Running
保持第一個運行狀態,運行第二個工程,得到結果
Running
則說明在系統中,mutex的name是在系統中是唯一的。
文章轉載至:https://blog.csdn.net/xwdpepsi/article/details/6346890
----------------------------------------------文章2----------------------------------------------
有時我們需要只允許運行應用程序的一個實例,當進程啟動時,如果發現應用程序的一個實例在運行,就自動停止運行。我們通常通過Mutex互斥體在Main函數中實現,通常的寫法是:
- [STAThread]
- static void Main()
- {
- bool createNew;
- using (System.Threading.Mutex m = new System.Threading.Mutex(true, Application.ProductName, out createNew))
- {
- if (createNew)
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Form1());
- }
- else
- {
- MessageBox.Show("Only one instance of this application is allowed!");
- }
- }
- }
此時我們忽略了一個重要的前提條件:Mutex的命名規則。以上的寫法在單用戶下運行沒有問題;在多用戶下,每個用戶都能啟動一個實例,也就不能保證單實例運行了。
如果需要在終端機服務器上使用,並且只允許一個實例的話,請使用下面的寫法:
- [STAThread]
- static void Main()
- {
- bool createNew;
- try
- {
- using (System.Threading.Mutex m = new System.Threading.Mutex(true, "Global\\" + Application.ProductName, out createNew))
- {
- if (createNew)
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Form1());
- }
- else
- {
- MessageBox.Show("Only one instance of this application is allowed!");
- }
- }
- }
- catch
- {
- MessageBox.Show("Only one instance of this application is allowed!");
- }
- }
以下是MSDN的說明:
在運行終端服務的服務器上,已命名的系統 mutex 可以具有兩級可見性。如果名稱以前綴“Global\”開頭,則 mutex 在所有終端服務器會話中均為可見。如果名稱以前綴“Local\”開頭,則 mutex 僅在創建它的終端服務器會話中可見。在這種情況下,服務器上各個其他終端服務器會話中都可以擁有一個名稱相同的獨立 mutex。如果創建已命名 mutex 時不指定前綴,則它將采用前綴“Local\”。在終端服務器會話中,只是名稱前綴不同的兩個 mutex 是獨立的 mutex,這兩個 mutex 對於終端服務器會話中的所有進程均為可見。即:前綴名稱“Global\”和“Local\”說明 mutex 名稱相對於終端服務器會話(而並非相對於進程)的范圍。
文章轉載自:https://www.itsvse.com/thread-3390-1-1.html
