282
Listing 14-3. Correct example for concurrent PMDK transaction
52 void increment(pop_type &pop) {
53
auto proot = pop.root();
54
pobj::transaction::run(pop, [&] {
55
proot->counter.get_rw() += 1;
56
}, proot->mtx);
57 }
The libpmemobj API allows us to specify locks that should be acquired and held for
the entire duration of the transaction. In the Listing 14-3 example, we pass the proot>mtx mutex object to the run() method as a third parameter.
Mutexes on Persistent Memory
Our previous examples used pmem::obj::mutex as a type for the mtx member in our root
data structure instead of the regular std::mutex provided by Standard Template Library.
The mtx object is a member of the root object that resides in persistent memory. The
std::mutex type cannot be used on persistent memory because it may cause persistent
deadlock.
A persistent deadlock happens if an application crash occurs while holding a mutex.
When the program starts, if it does not release or reinitialize the mutex at startup,
threads that try to acquire it will wait forever. To avoid such situations, libpmemobj
provides synchronization primitives that reside in persistent memory. The main feature
of synchronization primitives is that they are automatically reinitialized every time the
persistent object store pool is open.
For C++ developers, the libpmemobj-cpp library provides C++11-like
synchronization primitives shown in Table 14-1.
Chapter 14 ConCurrenCy and persistent MeMory
Précédent

- 306/457

Suivant