问题描述
我有一个围绕串行端口的包装类,看起来像这样:
I have a wrapper class around serial port which looks something like this:
static class HASPCLass
{
private static SerialPort m_port;
private static bool m_initialized;
private static int m_baudRate;
static readonly object _syncObject = new object();
public DoInitialization(int baudRate /*also could be other params*/)
{
lock(_syncObject)
{
if (!m_initialized)
{
Initialize(baudRate);
}
}
}
private Initialize(int baudrate /*also could have other params*/)
{
m_port.open(..);
m_baudRate = baudRate;
m_initialized = true;
}
private Uninitialize()
{
m_port.close();
m_initialized = false;
}
public void Read(byte[] buff)
{
lock(_syncObject)
{
//Other custom read stuff
m_port.Read(buff);
}
}
public void Write(byte [] buff)
{
lock(_syncObject)
{
//Other write related code
m_port.Write(buff);
}
}
public void Close()
{
lock(_syncObject)
{
if (m_initialized)
{
Uninitialize();
}
}
}
}
我尝试让这个类线程安全.有人对其进行了初始化——读取和写入可能从其他线程中使用——最后调用关闭.
I tried making this class thread safe. Someone initializes it - read and writes maybe used from other threads - and in the end calls Close.
现在想象一下,我有两个额外的静态方法来自其他类,它们执行以下操作:
Now Imagine I have two additional static methods from other class which do something like this:
public static void function1()
{
HASPClass.Read(...);
// Some other code
HASPClass.Write(...);
}
public static void function2()
{
HASPClass.Read(...);
// Some other code
HASPClass.Write(...);
}
为了整体线程安全,我还将这些函数封闭在锁中:
For overall thread safety I also enclosed these functions in locks:
public static void function1()
{
lock(otherlock1)
{
HASPClass.Read(...);
// Some other code
HASPClass.Write(...);
}
}
public static void function2()
{
lock(otherlock1)
{
HASPClass.Read(...);
// Some other code
HASPClass.Write(...);
}
}
因为调用读取和写入的顺序可能与 HASP 相关.我的问题是:现在我的最终方法(使用 function1 和 function2)是否正确/线程安全?
Because order in which read and writes are called might be relavant for the HASP. My question is: is now my final approach (of using function1 and function2) correct/thread safe?
推荐答案
既然你有点使用单例,那么只要函数不使用必须在 中锁定的资源,你不需要额外的锁就可以了.//其他一些代码
.该类本身是线程安全的,因为它使用相同的锁锁定变量的所有使用.这是最紧的.但请确保不要在注释后面的代码中引入死锁.
Since you kind of use a singleton you are fine without additional locks as long as the functions do not use resources that have to be locked in // Some other code
.
The class itself is thread safe because it locks all uses of the variables with the same lock. This is as tight as it gets. But make sure to not introduce dead locks in the code that lies behind the comments.
一般来说,您应该确保在所有线程完成之前没有人关闭您的对象.
In general you should make sure no one closes your object before all threads are done with it.
除了这个代码示例或多或少不一致.你不声明它是静态的,也不写任何返回类型.
Besides this code example is more or less inconsistent. You don't declare it static and write no return types and all.
从需要以特殊顺序发出命令的更高观点来看,我更正了该语句并说是的,您需要锁定它.
From the higher persepctive of the need to give commands in a special order I correct the statement and say yes you need to lock it.
但要小心死锁.一种更明确的方式如何出错(尽管我在您的示例代码中没有看到它发生):
But beware of dead locks. A more explicit way how this can go wrong (though I don't see it happening in your example code):
有 2 个线程可以持有锁.您的设备将始终向您发送 1,除非您向其发送 2,否则它将向您发送 2.
There are 2 threads that can hold the lock. Your device will always send you 1 except if you transmit 2 to it then it will send you 2.
线程 1 尝试先从设备读取 1,然后再读取 2,而不释放锁.
Thread 1 is trying to first read a 1 and after that a 2 from the device without releasing the lock.
现在假设以某种方式在接收到 1 后采取的行动启动了想要将 2 传输到设备的线程 2.但它不能因为线程 1 仍在等待,但它会永远等待,因为线程 2 无法传输.最常见的情况是与调用一起使用的 GUI 事件(这会导致其他线程执行代码).
Now suppose somehow the actions taken after receiving 1 start Thread 2 which wants to transmit 2 to the device. But it can not because Thread 1 is still waiting but it will wait forever because Thread 2 can not transmit. The most often case for this is GUI events used with invoke (which leads to an other thread executing code).
这篇关于function1 和 function2 是否以线程安全的方式使用我的串口类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!