分享
 
 
 

在.NET中的线程处理(5)

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Mutex [C#]

可以使用 Mutex 对象在线程之间以及跨进程进行同步。虽然 Mutex 不具备 Monitor 类的所有等待和脉冲功能,但它的确提供了创建可在进程之间使用的命名的互斥体的功能。

调用 WaitOne、WaitAll 或 WaitAny 可以请求 Mutex 的所属权。如果没有任何线程拥有它,则 Mutex 的状态为已发信号的状态。

如果某个线程拥有 Mutex,则该线程就可以在重复的等待-请求调用中指定同一个 Mutex,而不必阻塞其执行;但是,它必须释放与释放所属权相同的次数的 Mutex。

如果某个线程在拥有 Mutex 时正常终止,则 Mutex 的状态将被设置为已发信号的状态,并且下一个等待线程将获取所属权。Mutex 类与 Win32 CreateMutex 调用相对应。

下面的 C# 代码示例说明了 Mutex 的使用。

[C#]

using System;

using System.Threading;

public class MutexSample{

static Mutex gM1;

static Mutex gM2;

const int ITERS = 100;

static AutoResetEvent Event1 = new AutoResetEvent(false);

static AutoResetEvent Event2 = new AutoResetEvent(false);

static AutoResetEvent Event3 = new AutoResetEvent(false);

static AutoResetEvent Event4 = new AutoResetEvent(false);

public static void Main(String[] args){

Console.WriteLine("MutexSample.cs ...");

gM1 = new Mutex(true,"MyMutex");

// Create Mutext initialOwned, with name of "MyMutex".

gM2 = new Mutex(true);

// Create Mutext initialOwned, with no name.

Console.WriteLine(" - Main Owns gM1 and gM2");

AutoResetEvent[] evs = new AutoResetEvent[4];

evs[0] = Event1;

// Event for t1.

evs[1] = Event2;

// Event for t2.

evs[2] = Event3;

// Event for t3.

evs[3] = Event4;

// Event for t4.

MutexSample tm = new MutexSample( );

Thread t1 = new Thread(new ThreadStart(tm.t1Start));

Thread t2 = new Thread(new ThreadStart(tm.t2Start));

Thread t3 = new Thread(new ThreadStart(tm.t3Start));

Thread t4 = new Thread(new ThreadStart(tm.t4Start));

t1.Start();

// Calls Mutex.WaitAll(Mutex[] of gM1 and gM2).

t2.Start();

// Calls Mutex.WaitOne(Mutex gM1).

t3.Start();

// Calls Mutex.WaitAny(Mutex[] of gM1 and gM2).

t4.Start();

// Calls Mutex.WaitOne(Mutex gM2).

Thread.Sleep(2000);

Console.WriteLine(" - Main releases gM1");

gM1.ReleaseMutex( );

// t2 and t3 will end and signal.

Thread.Sleep(1000);

Console.WriteLine(" - Main releases gM2");

gM2.ReleaseMutex( );

// t1 and t4 will end and signal.

WaitHandle.WaitAll(evs);

// Waiting until all four threads signal that they are done.

Console.WriteLine("... MutexSample.cs");

}

public void t1Start(){

Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])");

Mutex[] gMs = new Mutex[2];

gMs[0] = gM1;

// Create and load an array of Mutex objects for WaitAll call.

gMs[1] = gM2;

Mutex.WaitAll(gMs);

// Waits until both Mutex objects are released.

Thread.Sleep(2000);

Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[])");

Event1.Set( );

// AutoResetEvent.Set( ) flagging method is done.

}

public void t2Start(){

Console.WriteLine("t2Start started, gM1.WaitOne( )");

gM1.WaitOne( );

// Waits until Mutex gM1 is released.

Console.WriteLine("t2Start finished, gM1.WaitOne( )");

Event2.Set( );

// AutoResetEvent.Set( ) flagging method is done.

}

public void t3Start(){

Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");

Mutex[] gMs = new Mutex[2];

gMs[0] = gM1;

// Create and load an array of Mutex objects for WaitAny call.

gMs[1] = gM2;

Mutex.WaitAny(gMs);

// Waits until either Mutex object is released.

Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");

Event3.Set( );

// AutoResetEvent.Set( ) flagging method is done.

}

public void t4Start(){

Console.WriteLine("t4Start started, gM2.WaitOne( )");

gM2.WaitOne( );

// Waits until Mutex gM2 is released.

Console.WriteLine("t4Start finished, gM2.WaitOne( )");

Event4.Set( );

// AutoResetEvent.Set( ) flagging method is done.

}

}

Interlocked [C#]

Interlocked 方法 CompareExchange、Decrement、Exchange 和 Increment 提供了一种简单机制,以同步对多个线程所共享的变量的访问。如果该变量位于共享内存中,则不同进程的线程就可以使用该机制。

Increment 和 Decrement 函数将递增或递减变量与检查结果值的操作组合起来。该原子操作对于多任务操作系统十分有用,在这种操作系统中,系统可以中断一个线程的执行,以便将一个处理器时间片授予另一个线程。如果没有这样的同步,则一个线程可能在递增某个变量后但尚未能够检查该变量的结果值之前被系统中断。然后,第二个线程可以递增同一个变量。当第一个线程收到其下一个时间片时,它将检查该变量的值,而现在该值已被递增了两次而不是一次。Interlocked 变量访问函数可以防止出现这种错误。

Exchange 函数自动交换指定变量的值。CompareExchange 函数组合以下两个操作:比较两个值以及根据比较的结果将第三个值存储在其中一个变量中。

在现代处理器中,Interlocked 类的方法通常可以由单个指令来实现。这样,Interlocked 类的方法就可以提供高性能的同步,并可用于生成较高级别的同步机制,如旋转锁。

由 Interlocked 公开的Exchange 和 CompareExchange 方法采用可以存储引用的 Object 类型的参数。但是,类型安全要求将所有参数严格类型化为 Object;不能在对其中一个方法的调用中简单地将对象强制转换为 Object。换言之,您必须创建 Object 类型的变量,将自定义对象赋给该变量,然后传递该变量。下面的简单 C# 代码示例将只允许使用单个调用来设置此属性。

[C#]

private Object _x;

public propery X x{

set(X value) {

Object ovalue = value;

Interlocked.CompareExchange(ref x, ovalue, null);

}

get(){

return (X) _x;

}

}

ReaderWriterLock

ReaderWriterLock 定义实现单个编写器/多个阅读器语义的锁。ReaderWriterLock:

开销非常低,足以大量使用(如针对每个对象的同步)。

尝试在编写器和阅读器之间寻求平衡。一旦请求了编写器锁,就不会再接受任何新的阅读器,直到该编写器具有访问权限为止。编写器和阅读器都不会被永久地拒绝访问。

支持超时,这是用于检测死锁的很有价值的功能。

支持事件缓存。这就使事件可以从争用程度最小的区域移动到争用程度最大的区域。换句话说,进程中的线程数限制了阅读器锁或编写器锁所需要的事件数。

支持由阅读器和编写器嵌套的锁。

支持旋转计数以避免在多处理器计算机上进行上下文切换。

支持用指示中间编写操作的返回参数升级到编写器锁和从编写器锁降级从而还原锁的状态的功能。

支持为调用应用程序代码释放锁的功能。RestoreLock 还原锁的状态并指示中间编写操作。

从最常见的失败(如创建事件失败)中恢复。换句话说,锁维护一致的内部状态并保持可用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有