2011-04-20 34 views
0
for (int i = 0; i < 100; i++) 
{ 
     // If current thread needs resource(i) then 

     Mutex mutex = new Mutex(false, "Mutex" + i.ToString()); 
     mutex.WaitOne(); 

     // synchronized access to resource(i) 

     mutex.ReleaseMutex(); 
} 

我们有100个资源,每个人都应该由单个线程并发访问同步访问命名mutexs(这是确定访问资源[2]和资源[5]同时),所以我使用了上面的代码。在这种情况下,命名互斥体的最佳选择是什么?最佳替代对每个资源

回答

2

如果这全部在一个进程中,那么根本就不需要命名互斥锁。只需创建一个N对象列表或数组并使用lock

const int NumLocks = 100; 
List<object> LockObjects = new List<object>(NumLocks); 

// to initialize 
for (int i = 0; i < NumLocks; ++i) 
{ 
    LockObjects.Add(new object()); 
} 

// and your loop 
for (int i = 0; i < NumLocks; ++i) 
{ 
    // if current thread needs lock[i] then 
    lock(LockObjects[i]) 
    { 
     // do whatever you need to do 
     // and then release the lock 
    } 
} 

或者,您可以锁定单个资源对象。如果他们真的是物体。我发现使用单独的锁对象更容易理解和维护,因为“资源”可能是一个方法或一组对象。锁对象是一个抽象,对我来说,它有助于理解。

如果多个进程需要这个,那么除了使用Mutex之外,我没有看到一个好的解决方案。但是,我建议在程序开始时创建这些对象的列表,并保持它们周围。这样,在循环中,你所要做的就是WaitOne - 每次循环中都不需要创建对象。

+0

实际上资源没有索引。他们有独特的名字,所以有'resource [key]'而不是'resource(i)',那么什么类型适合用作锁? – Xaqron 2011-04-20 23:42:29

+0

我会建议使用我发布的解决方案,并使用'List '作为锁。所以为了使用'resource [key]',你锁定了'LockObjects [key]'。如果'key'不是一个连续的整数,那么为这个锁建立一个'Dictionary '。只要锁对象和资源之间存在一对一的关系,你应该没问题。 – 2011-04-21 07:04:20

1

假设资源是引用类的实例,只需锁定每个资源即可。

var r = resource(i); 
lock (r) 
{ 
    // synchronized access to resource(i) 
} 
+0

不幸的是资源是'懒惰'的对象,我不喜欢不必要地唤醒它们,但这个想法很有创意。 – Xaqron 2011-04-20 23:22:25