Synchrnonization mechanisms
The synchronization mechanisms allow synchronization of threads and ensure secure sections.
Related classes
async::Lock
async::ModifiableLock
async::FutureSupport
Examples
Lock
The async::Lock
class implements the RAII idiom, meaning that declaring a async::Lock
object in
the code blocks other threads until execution exits the scope of the async::Lock
object. In the
example below, a global counter is presumably being incremented by two or more threads. To prevent
simultaneous modification of the counter, the lock object ensures that the increment operation is
performed by only one thread at a time, while others are paused and wait.
uint32_t counter = 0; // global (shared) resource
void callback()
{
// .. some code here
{ // visibility scope of the lock starts here
::async::Lock const lock;
++counter;
} // visibility scope of the lock ends here
// .. some code here
}
ModifiableLock
async::ModifiableLock
provides a secure section similar to async::Lock
and is also an RAII object.
However, it additionally allows the client to unlock it on demand using the unlock function.
uint32_t counter = 0; // global (shared) resource
void callback()
{
// .. some code here
::async::ModifiableLock const lock;
++counter;
// .. some code we want to be inside the secure section
lock.unlock();
// .. some code outside the secure section
}
FutureSupport
The async::FutureSupport
class implements the async::IFutureSupport
interface.
Calling the async::FutureSupport::wait()
method pauses the current thread until the future object is ready.
This class synchronizes the main thread with the worker thread and can be compared to barriers or
condition variables. The async::FutureSupport::notify()
function sets the bits of the future object,
allowing execution to return to the main thread.
Let’s introduce a runnable class AsyncCommandExecutor:
#include "async/FutureSupport.h"
// Asynchronous command executor
class AsyncCommandExecutor : private ::async::RunnableType
{
public:
AsyncCommandExecutor() : _future(0) {} // assume context ID is 0
async::FutureSupport _future;
}
Execute asynchronously, wait until its execution is complete and proceed.
// synchronization of asynchronous execution
void AsyncCommandExecutor::execWithWait
{
::async::execute(context, *this); // enqueue async execution
_future.wait(); // wait until the execution is done
// .. some code that may only be processes after "execute" is finished
}
void AsyncCommandExecutor::execute()
{
// Do something and notify when complete
_future.notify();
}