xtd 0.2.0
monitor_lock.cpp

Shows how to use xtd::threading::monitor class.

#include <xtd/threading/auto_reset_event>
#include <xtd/threading/interlocked>
#include <xtd/threading/thread>
#include <xtd/threading/thread_pool>
#include <xtd/console>
#include <xtd/lock>
#include <xtd/startup>
using namespace xtd;
using namespace xtd::threading;
namespace monitor_lock_example {
class sync_resource : public object {
public:
// Use a monitor to enforce synchronization.
void access() {
lock_(*this) {
console::write_line("Starting synchronized resource access on thread #{0}",
thread::current_thread().managed_thread_id());
if (thread::current_thread().managed_thread_id() % 2 == 0)
console::write_line("Stopping synchronized resource access on thread #{0}",
thread::current_thread().managed_thread_id());
}
}
};
class un_sync_resource : public object {
public:
// Do not enforce synchronization.
void access() {
console::write_line("Starting unsynchronized resource access on Thread #{0}",
thread::current_thread().managed_thread_id());
if (thread::current_thread().managed_thread_id() % 2 == 0)
console::write_line("Stopping unsynchronized resource access on thread #{0}",
thread::current_thread().managed_thread_id());
}
};
class app {
private:
inline static int num_ops = 0;
inline static auto_reset_event ops_are_done {false};
inline static sync_resource sync_res;
inline static un_sync_resource un_sync_res;
public:
static void main() {
// Set the number of synchronized calls.
num_ops = 5;
for (int ctr = 0; ctr <= 4; ++ctr)
thread_pool::queue_user_work_item(sync_update_resource);
// Wait until this WaitHandle is signaled.
ops_are_done.wait_one();
console::write_line("\t\nAll synchronized operations have completed.\n");
// Reset the count for unsynchronized calls.
num_ops = 5;
for (int ctr = 0; ctr <= 4; ctr++)
thread_pool::queue_user_work_item(un_sync_update_resource);
// Wait until this WaitHandle is signaled.
ops_are_done.wait_one();
console::write_line("\t\nAll unsynchronized thread operations have completed.\n");
}
static void sync_update_resource(std::any state) {
// Call the internal synchronized method.
sync_res.access();
// Ensure that only one thread can decrement the counter at a time.
if (interlocked::decrement(num_ops) == 0)
// Announce to Main that in fact all thread calls are done.
ops_are_done.set();
}
static void un_sync_update_resource(std::any state) {
// Call the unsynchronized method.
un_sync_res.access();
// Ensure that only one thread can decrement the counter at a time.
if (interlocked::decrement(num_ops) == 0)
// Announce to Main that in fact all thread calls are done.
ops_are_done.set();
}
};
}
startup_(monitor_lock_example::app::main);
// This example produces output similar to the following:
//
// Starting synchronized resource access on thread #6
// Stopping synchronized resource access on thread #6
// Starting synchronized resource access on thread #9
// Stopping synchronized resource access on thread #9
// Starting synchronized resource access on thread #2
// Stopping synchronized resource access on thread #2
// Starting synchronized resource access on thread #3
// Stopping synchronized resource access on thread #3
// Starting synchronized resource access on thread #8
// Stopping synchronized resource access on thread #8
//
// All synchronized operations have completed.
//
// Starting unsynchronized resource access on Thread #9
// Starting unsynchronized resource access on Thread #2
// Starting unsynchronized resource access on Thread #11
// Starting unsynchronized resource access on Thread #6
// Starting unsynchronized resource access on Thread #4
// Stopping unsynchronized resource access on thread #9
// Stopping unsynchronized resource access on thread #11
// Stopping unsynchronized resource access on thread #6
// Stopping unsynchronized resource access on thread #2
// Stopping unsynchronized resource access on thread #4
//
// All unsynchronized thread operations have completed.
//
static void write_line()
Writes the current line terminator to the standard output stream using the specified format informati...
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:44
Represents a thread synchronization event that, when signaled, resets automatically after releasing a...
Definition auto_reset_event.hpp:36
static int32 decrement(int32 &location) noexcept
Decrements a specified variable and stores the result, as an atomic operation.
static bool queue_user_work_item(const wait_callback &callback)
Queues a method for execution. The method executes when a thread pool thread becomes available.
static thread & current_thread() noexcept
Gets the currently running thread.
static void sleep(int32 milliseconds_timeout)
Suspends the current thread for a specified time.
#define startup_(main_method)
Defines the entry point to be called when the application loads. Generally this is set either to the ...
Definition startup.hpp:167
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.hpp:85
The xtd::threading namespace provides classes and interfaces that enable multithreaded programming....
Definition abandoned_mutex_exception.hpp:11
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8