我有一个函数,多个线程可以同时调用它。该函数有一个输入参数。例如,请考虑以下功能:
bool MyClass::run(QString moduleName)
{
qDebug() << QThread::currentThreadId();
...
}
我有两个使用此功能的选项。首先,我可以在run函数中使用互斥量,如下所示:
...
run("Reza"); // can be different for different threads
...
bool MyClass::run(QString moduleName)
{
qDebug() << QThread::currentThreadId();
QMutexLocker locker(&runMutex);
...
}
第二种是在调用此函数时使用互斥锁,如下所示:
...
runMutex.lock();
run("Reza"); // can be different for different threads
runMutex.unlock();
...
bool MyClass::run(QString moduleName)
{
qDebug() << QThread::currentThreadId();
...
}
哪一个更正确?输入参数(moduleName)是否在第一个选项中发生变化? (我的意思是在调用线程时向该函数传递一个不同的参数)
提前感谢您的帮助。 礼
答案 0 :(得分:1)
这两种方法都是正确的。但第一种方法更好。它还提供了代码可读性。
在第一个选项中,输入参数(局部变量)参数始终是安全的。因为每个线程都有自己的堆栈。
答案 1 :(得分:1)
在许多情况下,都是有意义的!在内部获取互斥锁的功能使得使用此功能更容易,并且通常更安全。但是,在明确使用互斥锁时,除了run()
方法执行的操作之外,您还希望执行其他操作,同时还要保持锁定。在这种情况下,你有另一个获取锁的功能,它不能调用内部锁定功能(好吧,除非互斥锁是一个递归的互斥锁,我认为它并不是一个好的理念)。出路是拥有该函数的一个版本,例如run_locked()
或具有不同参数的版本,该版本假设已获得锁定。
当使用显式锁定时(我通常会尽量避免这样做,因为我无法使用锁定来解释代码)我发现有相应的函数对是很有帮助的(我通常会使用{ {1}}设施):
std
通过锁定保护对象确保有获得的防护装置,即,用户不能仅在没有任何获得的锁定防护装置的情况下调用期望获得锁定的功能。通过获取错误锁定的锁定装置可能会导致误操作。
答案 2 :(得分:1)
DietmarKühl为选择所提到的方法提供了很好的答案。但是,我想补充一点,最小化关键部分始终是一个好习惯。因此,如果您不需要锁定整个“run()”函数,则不应使用任何提及的方法,而应保护“run()”中最小的可能关键部分。