没有得到一个在线示例来生动地演示这一点。在http://en.cppreference.com/w/cpp/header/shared_mutex上看到一个例子说明了一个例子,但是 仍然不清楚。有人可以帮忙吗?共享互斥和互斥之间的区别(为什么都存在于C++ 11并发中)?
回答
“共享互斥锁通常用于多个读者可以同时访问同一资源而不引起数据竞争的情况,但只有一个作者可以这样做。”
cppreference.com
当你需要读取/写入器锁这是有用的:https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
是的,我只有线程可以同时读取数据吗?为什么读者需要锁?只有修改需要锁定才能使底层的数据结构不被破坏? –
@AnandKulkarni读者需要锁定,否则他们可能会读取数据,而另一个线程正在写入相同的数据。这是为了防止数据竞争。通过读取/写入器锁定,多个读取器可以同时访问数据。 – 0xBADF00
通过使用正常互斥的,你能保证某种关键资源的独占访问 - 而不是其他。共享互斥通过允许访问的两级延伸此功能:共享和独占如下:
- 独占访问防止任何其它线程获取该互斥,正如与正常的互斥。其他线程是否尝试获取共享或独占访问权限并不重要。
- 共享访问允许多个线程获取互斥量,但是所有的只能在共享模式下使用。直到所有先前的共享持有者已经返回互斥量为止,才会授予独占访问权限(通常,只要独占请求正在等待,新共享对象在之后排队等待授予)。
一个典型的场景是数据库:多个线程同时读取一个数据和同一个数据并不重要。但修改数据库至关重要 - 如果某个线程正在读取数据,而另一个线程正在写入数据,则可能会收到不一致的数据。所以所有的阅读必须完成才能书写,新的阅读必须等到写作完成。写入后,可能会再次同时发生进一步的读取。
编辑:旁注:
为什么读者需要的锁?
这是为了防止作者在读取过程中获取锁而发生。此外,它还可以防止新读者在专门持有锁的情况下获得锁。
非常清楚的理解,我们不希望读者在修改正在发生时读取陈旧的数据,反之亦然,因为目前正在进行读取,所以我们不希望作者开始进行更改以保持数据一致 –
共享互斥锁有两个访问级别'shared'和'exclusive'。 多个线程可以获得共享访问权限,但只有一个可以拥有“独占”访问权限(包括没有共享访问权限)。
常见的情况是读/写锁。回想一下Data Race只能在两个线程访问相同的数据时发生其中至少有一个是写。
利用这些数据可能会被许多读者读取,但是当作者需要访问时,他们必须获得数据的独占访问权。
下面是一个示例(稍后从示例http://en.cppreference.com/w/cpp/thread/shared_mutex稍微改编)。
#include <iostream>
#include <mutex> // For std::unique_lock
#include <shared_mutex>
#include <thread>
std::mutex cout_mutex;
void log(const std::string& msg){
std::lock_guard guard(cout_mutex);
std::cout << msg << std::endl;
}
class ThreadSafeCounter {
public:
ThreadSafeCounter() = default;
// Multiple threads/readers can read the counter's value at the same time.
unsigned int get() const {
std::shared_lock lock(mutex_);//NB: std::shared_lock will shared_lock() the mutex.
log("get()-begin");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto result=value_;
log("get()-end");
return result;
}
// Only one thread/writer can increment/write the counter's value.
void increment() {
std::unique_lock lock(mutex_);
value_++;
}
// Only one thread/writer can reset/write the counter's value.
void reset() {
std::unique_lock lock(mutex_);
value_ = 0;
}
private:
mutable std::shared_mutex mutex_;
unsigned int value_ = 0;
};
int main() {
ThreadSafeCounter counter;
auto increment_and_print = [&counter]() {
for (int i = 0; i < 3; i++) {
counter.increment();
auto ctr=counter.get();
{
std::lock_guard guard(cout_mutex);
std::cout << std::this_thread::get_id() << ' ' << ctr << '\n';
}
}
};
std::thread thread1(increment_and_print);
std::thread thread2(increment_and_print);
std::thread thread3(increment_and_print);
thread1.join();
thread2.join();
thread3.join();
}
可能的部分输出:
get()-begin
get()-begin
get()-end
140361363867392 2
get()-end
140361372260096 2
get()-begin
get()-end
140361355474688 3
//Etc...
通知如何两个get()-begin()
返回显示,两个线程的读取期间保持共享锁。
- 1. 在模块之间共享互斥体
- 2. 在什么有增强共享互斥
- 3. 互斥锁与pthread_join之间的区别
- 4. C++ 11间原子学和互斥
- 5. 为什么互斥体不需要互斥体(并且该互斥体需要互斥体...)
- 6. C++共享互斥量和类实例的11个线程
- 7. 地图互斥C++ 11
- 8. 互斥或不互斥互斥?
- 9. 在C++ 98互斥锁中锁定变量共享数据互斥锁
- 10. C++ - 进程之间共享的互斥体
- 11. 共享内存并发算法与互斥锁/信号量之间的关系
- 12. 读写之间的互斥
- 13. 锁,互斥和临界区之间的区别
- 14. 互斥体和临界区之间的边界是什么?
- 15. boost进程间共享互斥和boost进程间条件变量共享互斥
- 16. 条件变量和共享互斥
- 17. 互斥和同步的区别?
- 18. 在C++中处理互斥11
- 19. 共享互斥锁的交替例程
- 20. 信号量和互斥量在实现中有什么区别?
- 21. 互斥并行
- 22. C++中互斥锁和临界区之间的性能差异
- 23. 写一个互斥的共享资源
- 24. Java中互斥线程的互斥量?
- 25. 互斥C#。如何系统识别互斥码
- 26. pthread进程共享互斥死锁
- 27. boost :: asio链vs共享互斥的
- 28. 互斥和条件变量之间的决定性区别是什么?
- 29. C++ 14 shared_timed_mutex VS C++ 11互斥体
- 30. iPhone上的“互斥”和NSCondition的共享内存
您应该查看[documentation](http://en.cppreference.com/w/cpp/thread/shared_mutex)而不是标题摘要(如链接所示)。顺便说一句,这是C++ 17而不是C++ 11。最接近的是C++ 14,它是'std :: shared_timed_mutex'。尽管如此,你有没有听说过[读者 - 作家锁定](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)? – WhiZTiM