什么是防止重入并确保某些操作获得锁定的正确方法?

Ada*_*ras 8 .net c# multithreading synchronization

我正在设计一个基类,当继承时,它将针对多线程环境中的上下文提供业务功能.每个实例可能具有长时间运行的初始化操作,因此我想使对象可重用.为了做到这一点,我需要能够:

  1. 为其中一个对象分配上下文以允许它执行其工作
  2. 防止在已有对象的情况下为其分配新上下文
  3. 在对象没有上下文时阻止访问某些成员

此外,每个上下文对象可以由许多工作对象共享.

是否有正确的同步原语适合我正在尝试做的事情?这是我提出的最符合我需要的模式:

private Context currentContext;

internal void BeginProcess(Context currentContext)
{
    // attempt to acquire a lock; throw if the lock is already acquired,
    // otherwise store the current context in the instance field
}

internal void EndProcess()
{
    // release the lock and set the instance field to null
}

private void ThrowIfNotProcessing()
{
    // throw if this method is called while there is no lock acquired
}
Run Code Online (Sandbox Code Playgroud)

使用上面的内容,我可以保护不应该访问的基类属性和方法,除非该对象当前处于处理状态.

protected Context CurrentContext
{
    get
    {
        this.ThrowIfNotProcessing();
        return this.context;
    }
}

protected void SomeAction()
{
    this.ThrowIfNotProcessing();

    // do something important
}
Run Code Online (Sandbox Code Playgroud)

我的初始是使用Monitor.Enter和相关的函数,但这不会阻止相同的线程重入(BeginProcess在原始线程上多次调用).

Han*_*ant 12

.NET中有一个不可重入的同步对象,您正在寻找一个信号量.

在你提交这个之前,确实让你的鸭子连续,并问自己如何在同一个线程上再次调用BeginProcess().这是非常非常不寻常的,你的代码必须重新进入才能实现.这通常只发生在具有调度程序循环的线程上,GUI应用程序的UI线程是一个常见示例.如果这是真的可能,你实际上使用信号量,那么你也将处理后果,你的代码将陷入僵局.因为它递归到BeginProcess并在信号量上停顿.因此永远不会完成,永远不能调用EndProcess().有一个很好的理由可以让Monitor和Mutex重新进入:)

  • 你提出了好点; 这个的主要功能是确保调用`BeginProcess`的基础结构代码正确地执行."一个优秀的程序员在穿越单行道之前会双向看待." 我不会允许信号量阻塞(我将以零超时调用`WaitOne`)并检查返回值以决定是否抛出.这将防止死锁情况. (3认同)

meh*_*dvd 9

您可以使用Semaphore.NET Framework 2.0附带的类.

信号量的良好用法是同步有限数量的资源.在您的情况下,您似乎拥有Context您希望在消费者之间共享的资源.

您可以创建信号量来管理资源,例如:

var resourceManager = new Semaphore(0, 10);
Run Code Online (Sandbox Code Playgroud)

然后BeginProcess使用以下方法等待方法中的资源可用:

resourceManager.WaitOne();
Run Code Online (Sandbox Code Playgroud)

最后EndProcess使用以下方法释放方法中的资源:

resourceManager.Release();
Run Code Online (Sandbox Code Playgroud)

这是一个关于在像你这样的情况下使用Semaphores 的好博客:

https://web.archive.org/web/20121207180440/http://www.dijksterhuis.org/using-semaphores-in-c/