mutex 用法_createsemaphore用法_pthread mutex init

电脑杂谈  发布时间:2017-03-08 04:02:27  来源:网络整理
mutex 用法

Mutex是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

三、作用域:

Mutex 有两种类型:未命名的局部 mutex 和已命名的系统 mutex。mutex 用法

局部互斥体仅存在于您的进程内。您的进程中任何引用表示 mutex 的 Mutex 对象的线程都可以使用它。每个未命名的Mutex 对象都表示一个单独的局部 mutex。

已命名的系统互斥体在整个操作系统中都可见,可用于同步进程活动

举例说明:

//局部Mutex

Mutex _localSync = new Mutex();

//系统Mutex

Mutex _processSync = new Mutex(true,"Name",out owned);

四、应用场景:

1、使用系统Mutex实现进程间同步与互斥--应用程序启动单实例。

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading;

usingSystem.Reflection;

usingSystem.Diagnostics;

usingNick.Win32Api;

publicclassSingleProgramInstance:IDisposable

{

privateMutex_processSync;

privatebool_owned=false;

publicSingleProgramInstance()

{

_processSync=newMutex(

true,

Assembly.GetExecutingAssembly().GetName().Name,

out_owned);

}

publicSingleProgramInstance(stringidentifier)

{

_processSync=newMutex(

true,

Assembly.GetExecutingAssembly().GetName().Name+identifier,

out_owned);

}

~SingleProgramInstance()

{

Release();

}

publicboolIsSingleInstance

{

get{return_owned;}

}

publicvoidRaiseOtherProcess()

{

Processproc=Process.GetCurrentProcess();

stringassemblyName=Assembly.GetExecutingAssembly().GetName().Name;

foreach(ProcessotherProcinProcess.GetProcessesByName(assemblyName))

{

//ignorethisprocess

if(proc.Id!=otherProc.Id)

{

IntPtrhWnd=otherProc.MainWindowHandle;

if(Win32Api.IsIconic(hWnd))

{

Win32Api.ShowWindowAsync(hWnd,Win32Api.SW_RESTORE);

}

Win32Api.SetForegroundWindow(hWnd);

return;

}

}

}

privatevoidRelease()

{

if(_owned)

{

//Ifweownethemutexthanreleaseitsothat

//other"same"processescannowstart.

_processSync.ReleaseMutex();

_owned=false;

}

}

#regionImplementationofIDisposable

publicvoidDispose()

{

//releasemutex(ifnecessary)andnotify

//thegarbagecollectortoignorethedestructor

Release();

GC.SuppressFinalize(this);

}

#endregion

}

2、使用局部Mutex实现进程内线程同步.

//ThiampleshowshowaMutexisusedtosynchronizeaccess

//toaprotectedresource.UnlikeMonitor,Mutexcanbeusedwith

//WaitHandle.WaitAllandWaitAny,andcanbepassedacross

//AppDomainboundaries.

usingSystem;

usingSystem.Threading;

classTest

{

//CreateanewMutex.Thecreatingthreaddoesnotownthe

//Mutex.

privatestaticMutexmut=newMutex();

privateconstintnumIterations=1;

privateconstintnumThreads=3;

staticvoidMain()

{

//Createthethreadsthatwillusetheprotectedresource.

for(inti=0;i<numThreads;i++)

{

ThreadmyThread=newThread(newThreadStart(MyThreadProc));

myThread.Name=String.Format("Thread{0}",i+1);

myThread.Start();

}

//Themainthreadexits,buttheapplicationcontinuesto

//rununtilallforegroundthreadshaveexited.

}

privatestaticvoidMyThreadProc()

{

for(inti=0;i<numIterations;i++)

{

UseResource();

}

}

//Thismethodrepresentsaresourcethatmustbesynchronized

//sothatonlyonethreadatatimecanenter.

privatestaticvoidUseResource()

{

//Waituntilitissafetoenter.

mut.WaitOne();

Console.WriteLine("{0}hasenteredtheprotectedarea",

Thread.CurrentThread.Name);

//Placecodetoaccessnon-reentrantresourceshere.

//Simulatesomework.

Thread.Sleep(500);

Console.WriteLine("{0}isleavingtheprotectedarear",

Thread.CurrentThread.Name);

//ReleasetheMutex.

mut.ReleaseMutex();

}

}

五、实现

C# Mutex 是实现Windows API 的Mutex其原型如下

调用CreateMutex可以创建或打开一个Mutex对象

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes,

BOOL bInitialOwner,

LPCTSTR lpName

);

其中参数lpMutexAttributes用来设定Mutex对象的安全描述符和是否允许子进程继承句柄。bInitialOwner表明是否将Mutex的持有者设置为调用线程。lpName参数设置Mutex的名字,该名字区分大小写并不能包含"",最大长度为MAX_PATH,可设置为NULL表明该Mutex为匿名对象。

如果调用成功,则返回Mutex的句柄,否则返回NULL,如果lpName不为NULL且调用前同名的Mutex已被创建,则返回同名Mutex的句柄,此时调用GetLastError将返回ERROR_ALREADY_EXISTS,参数bInitialOwner将被忽略。

还可以调用OpenMutex打开创建的非匿名Mutex,原型如下

HANDLE OpenMutex(

DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPCTSTR lpName

);

dotnetFramwork 代码如下:

privatestaticintCreateMutexHandle(boolinitiallyOwned,stringname,Win32Native.SECURITY_ATTRIBUTESsecurityAttribute,outSafeWaitHandlemutexHandle)

{

boolflag=false;

boolflag2=false;

boolflag3=false;

Label_0006:

flag2=false;

flag3=false;

mutexHandle=Win32Native.CreateMutex(securityAttribute,initiallyOwned,name);

intnum=Marshal.GetLastWin32Error();

if(!mutexHandle.IsInvalid||(num!=5))

{

returnnum;

}

RuntimeHelpers.PrepareConstrainedRegions();

try

{

RuntimeHelpers.PrepareConstrainedRegions();

try

{

}

finally

{

Thread.BeginThreadAffinity();

flag=true;

}

mutexHandle=Win32Native.OpenMutex(0x100001,false,name);

if(!mutexHandle.IsInvalid)

{

num=0xb7;

if(Environment.IsW2k3)

{

SafeWaitHandlehandle=Win32Native.OpenMutex(0x100001,false,name);

if(!handle.IsInvalid)

{

RuntimeHelpers.PrepareConstrainedRegions();

try

{

uintnum2=0;

IntPtrptr=mutexHandle.DangerousGetHandle();

IntPtrptr2=handle.DangerousGetHandle();

IntPtr[]handles=newIntPtr[]{ptr,ptr2};

num2=Win32Native.WaitForMultipleObjects(2,handles,true,0);

GC.KeepAlive(handles);

if(num2==uint.MaxValue)

{

if(Marshal.GetLastWin32Error()!=0x57)

{

mutexHandle.Dispose();

flag3=true;

}

}

else

{

flag2=true;

if((num2>=0)&&(num2<2))

{

Win32Native.ReleaseMutex(mutexHandle);

Win32Native.ReleaseMutex(handle);

}

elseif((num2>=0x80)&&(num2<130))

{

Win32Native.ReleaseMutex(mutexHandle);

Win32Native.ReleaseMutex(handle);

}

mutexHandle.Dispose();

}

gotoLabel_0166;

}

finally

{

handle.Dispose();

}

}

mutexHandle.Dispose();

flag3=true;

}

}

else

{

num=Marshal.GetLastWin32Error();

}

}

finally

{

if(flag)

{

Thread.EndThreadAffinity();

}

}

Label_0166:

if((flag2||flag3)||(num==2))

{

gotoLabel_0006;

}

if(num==0)


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-36375-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...