c ++:为其他函数锁定互斥锁但本身可以并行执行的函数
c++: Function that locks mutex for other function but can itself be executed in parallel
我有一个关于线程安全和互斥锁的问题。我有两个功能可能不会同时执行,因为这可能会导致问题:
std::mutex mutex;
void A() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
现在的问题是,函数 A 和 B 不应该同时执行。这就是我使用互斥量的原因。但是,如果从多个线程同时调用函数 B 则完全没问题。然而,这也被互斥锁阻止了(我不想要这个)。那么,有没有办法既保证A和B不同时执行,又让函数B并行执行多次呢?
您在 C++14 中有一个选项。
使用 std::shared_timed_mutex
.
A
会使用 lock
, B
would use lock_shared
如果 C++14 是一个选项,您可以使用共享互斥锁(有时称为 "reader-writer" 互斥锁)。基本上,在函数 A()
内,您将获得一个唯一(独占,"writer")锁,而在函数 B()
内,您将获得一个共享(非独占,"reader")锁.
只要共享锁存在,其他线程就不能独占获取互斥量(但可以非独占地获取);只要独占锁存在,互斥量就不能被任何其他线程获取。
结果是您可以让多个线程同时执行函数 B()
,而函数 A()
的执行阻止了 A()
和 B()
的并发执行其他主题:
#include <shared_mutex>
std::shared_timed_mutex mutex;
void A() {
std::unique_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::shared_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
请注意,即使 B()
的并发执行也会始终存在一些同步开销,这最终是否会给您带来比使用普通互斥锁更好的性能,这在很大程度上取决于内部和外部发生的情况这些功能 - 在提交更复杂的解决方案之前始终进行测量。
Boost.Thread 还提供了 shared_mutex
.
的实现
这很可能充满了错误,但由于您没有 C++14,您可以围绕 std::mutex
创建一个锁计数包装器并使用它:
// Lock-counting class
class SharedLock
{
public:
SharedLock(std::mutex& m) : count(0), shared(m) {}
friend class Lock;
// RAII lock
class Lock
{
public:
Lock(SharedLock& l) : lock(l) { lock.lock(); }
~Lock() { lock.unlock(); }
private:
SharedLock& lock;
};
private:
void lock()
{
std::lock_guard<std::mutex> guard(internal);
if (count == 0)
{
shared.lock();
}
++count;
}
void unlock()
{
std::lock_guard<std::mutex> guard(internal);
--count;
if (count == 0)
{
shared.unlock();
}
}
int count;
std::mutex& shared;
std::mutex internal;
};
std::mutex shared_mutex;
void A()
{
std::lock_guard<std::mutex> lock(shared_mutex);
// ...
}
void B()
{
static SharedLock shared_lock(shared_mutex);
SharedLock::Lock mylock(shared_lock);
// ...
}
...当然,除非您想深入了解 Boost。
我有一个关于线程安全和互斥锁的问题。我有两个功能可能不会同时执行,因为这可能会导致问题:
std::mutex mutex;
void A() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
现在的问题是,函数 A 和 B 不应该同时执行。这就是我使用互斥量的原因。但是,如果从多个线程同时调用函数 B 则完全没问题。然而,这也被互斥锁阻止了(我不想要这个)。那么,有没有办法既保证A和B不同时执行,又让函数B并行执行多次呢?
您在 C++14 中有一个选项。
使用 std::shared_timed_mutex
.
A
会使用 lock
, B
would use lock_shared
如果 C++14 是一个选项,您可以使用共享互斥锁(有时称为 "reader-writer" 互斥锁)。基本上,在函数 A()
内,您将获得一个唯一(独占,"writer")锁,而在函数 B()
内,您将获得一个共享(非独占,"reader")锁.
只要共享锁存在,其他线程就不能独占获取互斥量(但可以非独占地获取);只要独占锁存在,互斥量就不能被任何其他线程获取。
结果是您可以让多个线程同时执行函数 B()
,而函数 A()
的执行阻止了 A()
和 B()
的并发执行其他主题:
#include <shared_mutex>
std::shared_timed_mutex mutex;
void A() {
std::unique_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::shared_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
请注意,即使 B()
的并发执行也会始终存在一些同步开销,这最终是否会给您带来比使用普通互斥锁更好的性能,这在很大程度上取决于内部和外部发生的情况这些功能 - 在提交更复杂的解决方案之前始终进行测量。
Boost.Thread 还提供了 shared_mutex
.
这很可能充满了错误,但由于您没有 C++14,您可以围绕 std::mutex
创建一个锁计数包装器并使用它:
// Lock-counting class
class SharedLock
{
public:
SharedLock(std::mutex& m) : count(0), shared(m) {}
friend class Lock;
// RAII lock
class Lock
{
public:
Lock(SharedLock& l) : lock(l) { lock.lock(); }
~Lock() { lock.unlock(); }
private:
SharedLock& lock;
};
private:
void lock()
{
std::lock_guard<std::mutex> guard(internal);
if (count == 0)
{
shared.lock();
}
++count;
}
void unlock()
{
std::lock_guard<std::mutex> guard(internal);
--count;
if (count == 0)
{
shared.unlock();
}
}
int count;
std::mutex& shared;
std::mutex internal;
};
std::mutex shared_mutex;
void A()
{
std::lock_guard<std::mutex> lock(shared_mutex);
// ...
}
void B()
{
static SharedLock shared_lock(shared_mutex);
SharedLock::Lock mylock(shared_lock);
// ...
}
...当然,除非您想深入了解 Boost。