首页 > 解决方案 > 用C#实现多路复用器的硬件锁

问题描述

我们在系统中使用物理(解)多路复用器(时分、一个输入、多个输出)。

当一个通道被路由时,一个动作被执行(例如在路由连接上做某事)。在此操作期间,不允许其他人将多路复用器路由到另一个通道。

对于这种情况,我们目前使用如下lock语句

public void DoSomething(Action action, int channel)
{
    lock(_lock)
    {
        _multiplexer.Route(channel);
        action();
    }
}

在这个用例中使用lock合适还是有其他方法来处理锁定硬件设备?我经常阅读

保持锁紧

永远不要在锁内执行任意操作

这些规则适用于这种情况吗?

标签: c#.netlockingmutex

解决方案


是的,这是对锁的适当使用(与其他锁定机制相反)。但是,有些人可能会争辩说应该使用另一种跨进程类型的锁,例如命名互斥锁,因为如果可以启动多个进程,它们可能会同时访问硬件,从而可能损坏数据。

“保持锁紧”通常意味着您应该确保在持有锁时不要进行任何不必要的处理。例如,如果您需要分配一些空间来放入数据,通常可以在锁之外完成。第二条规则一般是为了避免死锁。例如,如果在传递到的动作内部DoSomething,代码将锁定不同的锁,并且在某些情况下,其他代码将在调用之前访问该锁DoSomething,如果这两个代码路径碰巧同时运行,你就会死锁(一个会持有这个锁并等待另一个,另一个会持有另一个锁并等待这个)。如果使用此代码的开发人员有纪律,在指定的操作中从不采取任何锁或进行任何不必要的处理,事情会正常工作,但这是一个很大的如果。

如果可能的话,将所有可以在通道上完成的操作编码起来会更安全(更好),这样所有的锁都隐藏在实现中,并且在锁定时不会调用外部代码握住。这样一来,不了解内部原理的人就无法编写导致死锁的代码。


推荐阅读