互锁与互斥,扩大规模的问题

Fri*_*ich 5 c# multithreading mutex scale

我遇到了问题,我在一些线程之间共享了一个C#(.NET)对象.线程可能会用另一个线程替换该对象.使用Asynchronous框架从TCP/IP连接中唤醒线程.

序列:

线程(等待连接) - >异步回调 - >做一些线程安全的事情 - >访问共享对象 - >做一些线程安全的事情.

1.解决方案互斥:

Object sharedObject = new Object();
Mutex objectMutex = new Mutex();

void threadCallback()
{
  Object newObject = new Object();

  // some processing

  objectMutex.lock();
  // do exchange sharedObject with newObject if needed
  // very little processing here
  objectMutex.unlock();

  // some processing
}
Run Code Online (Sandbox Code Playgroud)

2.解决方案联锁

Object sharedObject = new Object();
int usingSharedObject = 0;

void threadCallback()
{
  Object newObject = new Object();

  // some processing

  // poll until we lock
  while(1 == Interlocked.Exchange(ref usingSharedObject , 1))
  {
    // do exchange sharedObject with newObject if needed
    // very little processing here
    Interlocked.Exchange(ref usingSharedObject , 0); // free lock
  }

  // some processing
}
Run Code Online (Sandbox Code Playgroud)

什么更快,更好地扩展?

我希望只要没有多个线程同时进行轮询,第二个解决方案就会更快.第二种解决方案甚至可以随机休眠,以便轮询不会占用任何处理时间.如果我确实需要处理大量的TCP/IP连接,那么第一个解决方案看起来更干净.由于我在关于TCP/IP处理的锁定部分中进行的处理很少,是否会出现任何向上扩展的问题?

如何在threadCallback()函数的开头创建对象.

在我的C++背景中,我总是在这种情况下使用内存池,因为我必须使用安全的.NET有一种快速创建新对象的方法,或者.NET平台在这个领域中表现良好.

最好的祝福,

弗里德里希

Rem*_*anu 5

您的互锁操作不正确.自旋锁通常看起来像这样:

int sharedLock = 0;

void callback()
{

do {
 int existingState = Interlocked.CompareExchange(ref sharedLock, 1, 0);
 if (0 == existingState) {
  break;
 }
} while (true);

try
{
 // operate on the shared state
}
finally
{
 int existingState = Interlocked.Exchange(ref sharedLock, 0);
 Debug.Assert (1 == existingState);
}
Run Code Online (Sandbox Code Playgroud)

}

至于使用一个与另一个的原因,它主要取决于持有锁时所完成的操作类型.非常短的操作(短算术加/减法,简单状态标志改变等)更适合自旋锁.在spinlock下不能进行繁重的操作(分配,IO访问),因此必须在真正的互斥锁下完成.


Mit*_*ers 2

查看第二个示例的工作方式,似乎如果未获取锁,您将退出,从而跳过代码的重要部分。

Mutex 方法更容易理解,而且我没有遇到任何性能问题。