我正在从Class构造几个对象,并使用这些类中的特定函数来启动Threads。现在,包含构造这些对象的成员函数的Class具有静态私有Mutex成员。我将此静态成员传递给构造函数,并在每个构造函数内部,传递的Mutex(可能通过引用)被分配给另一个本地成员。
如果我然后使用这些本地Mutex成员中的每一个来确保线程安全,我能够实现这一目标吗?我指望这个事实,无论存在多少个包含Thread函数的对象的不同实例,因为它们都指向相同的Mutex对象,线程安全性确保正确使用。
请在下面找到代码表示代码段:
Class ThreadClass
{
private Mutex myCopyOfMutex;
public ThreadClass(Mutex _globalMutex)
{
myCopyOfMutex = _globalMutex;
}
public ThreadFunction()
{
// Wait until it is safe to enter.
myCopyOfMutex.WaitOne();
// critical code
// Release the Mutex.
myCopyOfMutex.ReleaseMutex();
}
}
Class MotherClass
{
private static Mutex mut = new Mutex();
ThreadClass one = new ThreadClass(mut); // first instance
Threadclass two = new ThreadClass(mut); // second instance
// Assign the Thread function to run on separate Thread
}
答案 0 :(得分:3)
是的,它会起作用。不,它不是通过引用传递的。
传递 参考与传递 之间存在重要差异参考。
当您将引用类型传递给方法时,它通常作为引用传递:
SomeMethod(mutex);
要通过引用传递参数,请使用ref
关键字:
SomeMethod(ref mutex);
方法签名中的参数也必须使用ref
关键字声明:
public void SomeMethod(ref Mutex mutex) {
通过引用传递变量 意味着您传递对变量的引用,而不是变量中包含的引用的副本。然后,该方法可以更改变量本身,而不仅仅是引用指向的对象。
在大多数情况下,在这种情况下,您应该以常规方式传递参数。只有当您因特定原因需要时,才能通过引用传递。
答案 1 :(得分:1)
(答案完全重写,旧答案在底部)
通常,System.Threading.Mutex用于进程间通信。如果您只想在同一个进程中同步线程,那么使用全权重的Mutex是一种过度杀伤力。您可以使用lock
运算符的任何对象:
Class ThreadClass
{
// static is important, this way the object is shared among all
// class instances
private static object myMutex = new object();
public ThreadFunction()
{
// Wait until it is safe to enter.
lock(myMutex)
{
// critical code
}
// the mutex is automatically released after leaving the block.
}
}
Class MotherClass
{
ThreadClass one = new ThreadClass(); // first instance
Threadclass two = new ThreadClass(); // second instance
// Assign the Thread function to run on separate Thread
}
lock
- 方法的优点是早期返回和异常安全的可能性(想象一下如果关键代码抛出异常会发生什么;但请看Eric Lippert的article about exceptions under lock)。
如果整个方法很关键,并且课程中有不再关键方法,那么您可以更简单地执行此操作:
Class ThreadClass
{
[MethodImpl(MethodImplOptions.Synchronized)]
public ThreadFunction()
{
// critical code
}
}
Class MotherClass
{
ThreadClass one = new ThreadClass(); // first instance
Threadclass two = new ThreadClass(); // second instance
// Assign the Thread function to run on separate Thread
}
(旧答案保留在这里是为了保持一致)
所有类实例都通过C#中的引用传递。如果您的互斥锁是一个类(例如,它是System.Threading.Mutex
),它将自动通过引用传递。
查看here了解更多信息。
校正:
正如@Guffa正确指出的那样,您不会通过引用传递类实例,而是通过值将引用传递给类实例(如果不使用ref
关键字)。为了你的目的,它实际上几乎是一样的。不同之处在于传递的引用中的更改在被调用者之外是不可见的。
答案 2 :(得分:1)
是互斥是通过引用传递的,因为它们是类类型而不是结构类型
答案 3 :(得分:0)
从您的简报中,我假设您正在使用Mutex来同步共享资源访问。
Mutex是一种托管引用类型,它使用Win32中的非托管互斥锁。要回答您的问题,是的,它是参考类型。
但是你的问题让我想到了两点
我的建议是,如果您担心要共享相同的Mutex实例,请继续创建一个名为Mutex(检查Mutex的构造函数重载)。卧底操作系统将确保这个名为Mutex的同步访问。
我的建议是,静态变量由JIT在与AppDomain关联的特殊堆中分配。这称为Loader堆。除非您卸载/重新加载AppDomain,否则此加载程序堆永远不会收集垃圾。所以我的观点是,如果你使用Mutex作为静态成员,那么你可能最终会持有很多互斥锁句柄。