The class unique_lock is a general-purpose mutex ownership wrapper allowing deferred locking,
time-constrained attempts at locking, recursive locking, transfer of lock ownership,
and use with condition variables.
The class shared_lock is a general-purpose shared mutex ownership wrapper allowing deferred locking, timed locking and transfer of lock ownership. Locking a shared_lock locks the associated shared mutex in shared mode (to lock it in exclusive mode, std::unique_lock can be used)
Shared mutexes are usually used in situations when multiple readers can access the same resource at the same time without causing data races, but only one writer can do so.
Most of the time, if you think you want a recursive mutex, you probably need to change
your design instead. A common use of recursive mutexes is where a class is designed to be
accessible from multiple threads concurrently, so it has a mutex protecting the member data.
Synchronizing concurrent operations:
header
<condition_variable>
std::condition_variable is preferred then
std::condition_variable_any.
Pattern:
Producer:
modify data.
unlock mutex.
std::condition_variable notify_one
Waiter:
std::unique_lock
std::condition_variable wait
modify data.
unlock mutex.
header
<future>
std::async
Just as with std::thread, if the arguments are
rvalues,
the copies are created by
moving the originals.
This allows the use of move-only types as both the function
object and the arguments.
#include <string>
#include <future>
struct X
{
void foo(int,std::string const&);
std::string bar(std::string const&);
};
X x;
auto f1=std::async(&X::foo,&x,42,"hello"); // Calls p->foo(42,"hello") where p is &x
auto f2=std::async(&X::bar,x,"goodbye"); // Calls tmpx.bar("goodbye") where tmpx is a copy of x
struct Y
{
double operator()(double);
};
Y y;
auto f3=std::async(Y(),3.141); // Calls tmpy(3.141) where tmpy is move-constructed from Y()
auto f4=std::async(std::ref(y),2.718); // Calls y(2.718)
X baz(X&);
std::async(baz,std::ref(x)); // Calls baz(x)
class move_only
{
public:
move_only();
move_only(move_only&&)
move_only(move_only const&) = delete;
move_only& operator=(move_only&&);
move_only& operator=(move_only const&) = delete;
void operator()();
};
auto f5=std::async(move_only()); // Calls tmp() where tmp is constructed from std::move(move_only())
std::packaged_task
The std::packaged_task object is thus a callable object, and it can be wrapped in a
std::function object, passed to a std::thread as the thread function, passed to another
function that requires a callable object, or even invoked directly.
std::promise
some_promise.set_exception(std::make_exception_ptr(std::logic_error("foo ")));
Another way to store an exception in a future is to destroy the std::promise or
std::packaged_task associated with the future without calling either of the set functions on
the promise or invoking the packaged task.
In either case, the destructor of the std::promise or std::packaged_task will store a
std::future_error exception with an error code of std::future_errc::broken_promise
in the associated state if the future isn’t already ready;
std::future
// get shared_future
std::promise< std::map< SomeIndexType, SomeDataType, SomeComparator,
SomeAllocator>::iterator> p;
auto sf=p.get_future().share();
C++ time class:
namespapce
std::literals::chrono_literals
contains
literals and
chrono_literals
std::ratio has predefined type.
using namespace std::literals::chrono_literals
using namespace std::literals
using namespace std::chrono_literals
Fixed width integer types
Duration literals
user defined literals from cppref and
c++11 faq
There are four kinds of literals that can be suffixed to make a user-defined literal:
- integer literal: accepted by a literal operator taking a single unsigned long long or const char* argument.
- floating-point literal: accepted by a literal operator taking a single long double or const char* argument.
- string literal: accepted by a literal operator taking a pair of (const char*, size_t) arguments.
- character literal: accepted by a literal operator taking a single char argument.
using namespace std::chrono_literals;
auto one_day=24h;
auto half_an_hour=30min;
auto max_time_between_messages=30ms;
Explicit conversions can be done with
std::chrono::duration_cast<>
std::chrono::milliseconds ms(54802);
std::chrono::seconds s;
std::chrono::duration_cast<std::chrono::seconds>(ms);
Time points
std::chrono::time_point<>
header:
<experimental/future>
std::experimental::when_all
std::experimental::when_any
std::experimental::latch
std::experimental::barrier
more basic, and potentially therefore has lower overhead
std::experimental::flex_barrier
more flexible, but potentially has more overhead.