C++11 equivalent to boost shared_mutex
I tried but failed to get shared_mutex
into C++11. It has been proposed for a future standard. The proposal is here.
Edit: A revised version (N3659) was accepted for C++14.
Here is an implementation:
http://howardhinnant.github.io/shared_mutex
http://howardhinnant.github.io/shared_mutex.cpp
Is it smart to replace boost::thread and boost::mutex with c++11 equivalents?
There are several differences between Boost.Thread and the C++11 standard thread library:
- Boost supports thread cancellation, C++11 threads do not
- C++11 supports
std::async
, but Boost does not - Boost has a
boost::shared_mutex
for multiple-reader/single-writer locking. The analogousstd::shared_timed_mutex
is available only since C++14 (N3891), whilestd::shared_mutex
is available only since C++17 (N4508). - C++11 timeouts are different to Boost timeouts (though this should soon change now Boost.Chrono has been accepted).
- Some of the names are different (e.g.
boost::unique_future
vsstd::future
) - The argument-passing semantics of
std::thread
are different toboost::thread
--- Boost usesboost::bind
, which requires copyable arguments.std::thread
allows move-only types such asstd::unique_ptr
to be passed as arguments. Due to the use ofboost::bind
, the semantics of placeholders such as_1
in nested bind expressions can be different too. - If you don't explicitly call
join()
ordetach()
then theboost::thread
destructor and assignment operator will calldetach()
on the thread object being destroyed/assigned to. With a C++11std::thread
object, this will result in a call tostd::terminate()
and abort the application.
To clarify the point about move-only parameters, the following is valid C++11, and transfers the ownership of the int
from the temporary std::unique_ptr
to the parameter of f1
when the new thread is started. However, if you use boost::thread
then it won't work, as it uses boost::bind
internally, and std::unique_ptr
cannot be copied. There is also a bug in the C++11 thread library provided with GCC that prevents this working, as it uses std::bind
in the implementation there too.
void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));
If you are using Boost then you can probably switch to C++11 threads relatively painlessly if your compiler supports it (e.g. recent versions of GCC on linux have a mostly-complete implementation of the C++11 thread library available in -std=c++0x
mode).
If your compiler doesn't support C++11 threads then you may be able to get a third-party implementation such as Just::Thread, but this is still a dependency.
What is the equivalent of boost::upgrade_to_unique_lock in STL?
C++11 doesn't provide shared locks at all. C++14 does, but doesn't allow them to be upgraded to exclusive locks; you'd need a second mutex for that, something like:
mutable std::shared_timed_mutex read_mutex;
std::mutex write_mutex;
void Write() {
std::shared_lock read_lock(read_mutex);
// ... Verification statements
std::lock_guard write_lock(write_mutex);
// ... Writing statements
}
You'll need to take some care only to acquire the write lock while already holding the read lock, to avoid deadlocks. If you have a working Boost solution, it might be better to stick to that until the standard library provides equivalent functionality.
why C++0x standard committee rejected boost::shared_mutex?
Anthony Williams is an influential member of the C++ standards committee. He co-authored many of the proposals that led to the inclusion of the thread library in the C++11 Standard. You can read his objections in this commentary. Nevertheless, it did make it into C++17.
boost::shared_mutex slower than a coarse std::mutex on Linux
It turns out that boost::shared_mutex
is "suboptimal" on Linux.
The current (as of boost 1.59) implementation of boost::shared_mutex for 'pthread' is pretty suboptimal as it's using a heavyweight mutex to guard the internal mutex state... [when access concurrency is high] the shared mutex is effectively exclusive.
Hooray for boost and the many hours of my life it has stolen.
Related Topics
Statically Declared 2-D Array C++ as Data Member of a Class
Most Optimized Way of Concatenation in Strings
Declare a Reference and Initialize Later
How to Use Something Like Std::Vector<Std::Mutex>
Generating an Interface Without Virtual Functions
Is There a Use for Function Declarations Inside Functions
Alternative Function in iOStream.H for Getch() of Conio.H
"If Constexpr" in C++17 Does Not Work in a Non-Templated Function
Vector That Can Have 3 Different Data Types C++
Detect When Multiple Enum Items Map to Same Value
How to Test Whether a C++ Class Has a Default Constructor (Other Than Compiler-Provided Type Traits)
What's the Fastest Way to Pack 32 0/1 Values into the Bits of a Single 32-Bit Variable
How to Make Reading from 'Std::Cin' Timeout After a Particular Amount of Time
What's the Precedence of Comma Operator Inside Conditional Operator in C++