int*_*nt3 8 qt multithreading mutex
如果在函数中定义了互斥锁,它的锁是否适用于从该函数调用的函数?即
void f () {
Mutex mutex;
g();
}
Run Code Online (Sandbox Code Playgroud)
锁仍然适用于g()中的任何数据修改吗?
另外,我是否正确地说,类方法中定义的锁只适用于该类的特定实例?含义:
Class Foo;
Foo foo1, foo2;
(In thread 1) foo1.bar();
(In thread 2) foo2.bar();
Run Code Online (Sandbox Code Playgroud)
每个电话会同时发生吗?
如果有人可以解释/指出解释互斥体背后机制的链接,那将是一个很好的奖励.谢谢!我目前正在使用Qt Thread库,如果该信息有帮助的话.
sth*_*sth 17
在您的示例中,您实际上并未锁定互斥锁,因此它不会阻止不同的线程同时访问该函数.您还在函数内部声明了互斥锁,以便每个函数调用使用不同的本地互斥对象.即使锁定此互斥锁,每个函数调用也会锁定不同的互斥锁对象,而不会阻止同时访问.
一个更好的策略是这样的设置:
class A {
QMutex mutex;
void f() {
QMutexLocker ml(mutex); // Acquire a lock on mutex
g();
// The lock on the mutex will be released when ml is destroyed.
// This happens at the end of this function.
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下mutex,只要ml存在就锁定,因此在线程花费的时间内也是如此g().如果另一个线程f()在此期间调用它将阻止创建其ml对象,直到第一个线程离开该函数并且新线程可以获得锁定mutex.
一个互斥体是你抓住的东西,并且会阻止任何其他线程试图抓住它,直到你从抓取线程中释放它.
在您的问题中,您有一个函数f分配Mutex实例.这还不足以锁定它.你必须专门调用mutex.lock()(在Qt中,但一般情况下,除非你使用pthread,在这种情况下使用pthread_mutex_lock并享受低级别,平台相关的东西.Qt非常好地抽象).
这是Qt的一个例子
void MyClass::doStuff( int c )
{
mutex.lock();
a = c;
b = c * 2;
mutex.unlock();
}
Run Code Online (Sandbox Code Playgroud)
一旦你获得锁定,对g()的调用将从获得锁定的线程完成,因此它将在该调用中独自一人,假设你没有从代码的另一部分调用来自其他线程的g().锁定并不意味着它将停止所有其他线程.它将阻止线程尝试获取相同的锁,直到锁被释放.
如果这是您的线程到达g()的唯一方法,那么您将在该访问上进行同步.
对于问题的第二部分,如果互斥锁是实例属性,那么它们将是两个不同的互斥锁.您将必须声明并实例化类互斥实例,并将其引用为您的锁定.在这种情况下,任何在类中锁定类互斥锁的方法调用的尝试都将被有效地同步,这意味着没有两个线程将一起执行该方法.
例如(我没有Qt,因此我无法编译此代码,并且我在2年前停止使用它编码,所以它无法工作)
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
QMutex mutex;
};
Run Code Online (Sandbox Code Playgroud)
好的,在这种情况下,假设你有两个线程,1和2,以及类Foo,a和b的两个实例.假设线程1调用a.method()并且线程2调用b.method().在这种情况下,两个互斥锁是不同的实例,因此每个线程将独立地执行调用,并且并行运行.
假设您有两个线程,1和2,以及在两个线程之间共享的类Foo的一个实例.如果线程1调用a.method()然后线程2调用a.method(),则线程2将停止并等待直到释放互斥锁.
最后,
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
static QMutex mutex;
};
QMutex Foo::mutex;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,互斥锁是一个类静态变量.每个对象实例只有一个互斥锁实例.假设您遇到与上述第一种情况相同的情况:两个线程和两个实例.在这种情况下,当第二个线程试图调用b.method()时,它必须等待第一个线程完成a.method(),因为锁现在是唯一的并且在类的所有实例之间共享.
有关更多信息,Qt有一个很好的多线程教程
https://doc.qt.io/qt-5/threads.html
| 归档时间: |
|
| 查看次数: |
9330 次 |
| 最近记录: |