我需要一些线程的同步机制。我想知道下面哪个是更好的方法实现?
classA{
public:
int sharedResourceA;
pthread_mutex_t mutex1;
functionA();
int nonSharedResources;
}
classA::functionA(){
pthread_mutex_lock( &mutex1 );
use sharedResourceA;
pthread_mutex_unlock( &mutex1 );
}
classA objA;
pthread_mutex_lock(&objA.mutex1) //use lock because another thread can call obj.functionA
use objA.sharedResources;
pthread_mutex_unlock(&objA.mutex1)
use objA.nonSharedResources = blah //without lock because is non shared
或者我不应该在classA上创建一个锁,而是在应用程序中创建一个锁。例如:
classA objA;
pthread_mutex_t mutex2;
pthread_mutex_lock(mutex2) //use lock because another thread can call obj.functionA
use objA.sharedResources;
pthread_mutex_unlock(mutex2)
pthread_mutex_lock(mutex2) //use lock because another thread can call obj.functionA
functionA();
pthread_mutex_unlock(mutex2)
use objA.nonSharedResources = blah //without lock because is non shared
答案 0 :(得分:4)
首先 - 在c ++中执行锁定的惯用方法是创建一个使用RAII的锁类。
然后你可以去
Lock l(mutex1);
// do stuff under mutex1 lock;
// Lock is freed at end of scope
(我打赌加强锁定,我们自己做了)
二。 (范围问题)。如果A类在内部使用共享资源,那么它应该在内部锁定它们。否则
当调用者是使用共享资源的人并使用classA,funcX和文件W组成更大的东西时,应该使用应用程序级锁。注意,在这种情况下,classA可能仍然有自己的内部锁
答案 1 :(得分:1)
如果functionA使用某些共享资源,它应该确保它以正确的方式访问它们 - 即确保线程安全。这是对你提出的第一个选项的投票。
有更有效的方法可以使用互斥锁:请参阅boost :: recursive_mutex和boost :: recursive_mutex :: scoped_lock。使用此功能,您可以确保即使某个关键部分出现问题,您的互斥锁也会被解锁。例如:
using namespace boost;
struct C
{
function f ()
{
//non critical section
//...
//critical section
{
//acquire the mutex
recursive_mutex::scoped_lock lock(mutex);
//do whatever you want. Can throw if it needs to:)
}//exiting the scope causes the mutex to be released
//non critical section again
}
private:
recursive_mutex mutex;
}
答案 2 :(得分:0)
我想说第一个更好,因为如果你需要多次实例化ClassA,你需要为第二个解决方案创建尽可能多的全局锁。
如果你在类中执行它并且隐藏了使用受保护资源的方法,它也会尊重对象封装。此外,如果共享资源未被共享,则在代码中更改类方法,而不是在使用全局锁时重构资源的每个用法。