xtd 0.2.0
Loading...
Searching...
No Matches
xtd::threading::monitor Class Reference
Inheritance diagram for xtd::threading::monitor:
xtd::static_object

Definition

Provides a mechanism that synchronizes access to objects.

Provides a mechanism that synchronizes access to objects.
Definition monitor.h:127
#define static_
This keyword is use to represent a static object. A static object can't be instantiated (constructors...
Definition static.h:37
#define core_export_
Define shared library export.
Definition core_export.h:13
Inheritance
xtd::static_objectxtd::threading::monitor
Header
#include <xtd/threading/monitor>
Namespace
xtd::threading
Library
xtd.core
Examples
The following example uses the xtd::threading::monitor class to synchronize access to a single instance of a random number generator represented by the xtd::random class. The example creates ten threads, each of which executes asynchronously on a thread pool thread. Each thread generates 10,000 random numbers, calculates their average, and updates two procedure-level variables that maintain a running total of the number of random numbers generated and their sum. After all threads have executed, these two values are then used to calculate the overall mean.
#include <xtd/threading/interlocked>
#include <xtd/threading/monitor>
#include <xtd/threading/thread>
#include <xtd/console>
#include <xtd/literals>
#include <xtd/random>
#include <xtd/startup>
#include <array>
#include <vector>
using namespace xtd;
using namespace xtd::threading;
namespace monitor_example {
class program {
public:
static void main() {
auto threads = std::vector<thread> {};
auto rnd = xtd::random {};
auto total = 0_s64;
auto n = 0;
for (auto thread_ctr = 0; thread_ctr < 10; ++thread_ctr)
threads.push_back(thread::start_new([&] {
auto values = std::array<int, 10000> {};
auto thread_total = 0;
auto thread_n = 0;
auto ctr = 0;
monitor::enter(rnd);
// Generate 10,000 random integers
for (ctr = 0; ctr < 10000; ++ctr)
values[ctr] = rnd.next(0, 1001);
monitor::exit(rnd);
thread_n = ctr;
for (auto value : values)
thread_total += value;
console::write_line("Mean for task {0,2}: {1:N2} (N={2:N0})",
thread::current_thread().managed_thread_id(),
(thread_total * 1.0) / thread_n, thread_n);
interlocked::add(n, thread_n);
interlocked::add(total, thread_total);
}));
try {
for (auto& thread : threads)
thread.join();
console::write_line("\nMean for all tasks: {0:N2} (N={1:N0})",
(total * 1.0)/n, n);
}
catch (const system_exception& e) {
console::write_line("{0}: {1}", e.get_type().name(), e.message());
}
}
};
}
startup_(monitor_example::program::main);
// This example produces output similar to the following:
//
// Mean for task 4: 498.90 (N=10000)
// Mean for task 2: 499.92 (N=10000)
// Mean for task 7: 503.12 (N=10000)
// Mean for task 5: 499.41 (N=10000)
// Mean for task 3: 498.58 (N=10000)
// Mean for task 8: 496.71 (N=10000)
// Mean for task 10: 501.49 (N=10000)
// Mean for task 6: 498.84 (N=10000)
// Mean for task 9: 502.72 (N=10000)
// Mean for task 11: 498.69 (N=10000)
//
// Mean for all tasks: 499.84 (N=100000)
Represents a pseudo-random number generator, a device that produces a sequence of numbers that meet c...
Definition random.h:40
Defines the base class for predefined exceptions in the xtd namespace.
Definition system_exception.h:25
Creates and controls a thread, sets its priority, and gets its status.
Definition thread.h:41
#define startup_(main_method)
Defines the entry point to be called when the application loads. Generally this is set either to the ...
Definition startup.h:166
@ n
The N key.
@ e
The E key.
The xtd::threading namespace provides classes and interfaces that enable multithreaded programming....
Definition abandoned_mutex_exception.h:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10
Because they can be accessed from any task running on a thread pool thread, access to the variables total and n must also be synchronized. The xtd::threading::interlocked::add method is used for this purpose.

The following example demonstrates the combined use of the xtd::threading::monitor class (implemented with the lock_ keyword), the xtd::threading::interlocked class, and the xtd::threading::auto_reset_event class. It defines two classes, sync_resource and un_sync_resource, that respectively provide synchronized and unsynchronized access to a resource. To ensure that the example illustrates the difference between the synchronized and unsynchronized access (which could be the case if each method call completes rapidly), the method includes a random delay: for threads whose xtd::threading::thread::managed_thread_id property is even, the method calls xtd::threading::thread::sleep to introduce a delay of 2,000 milliseconds.
#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)
thread::sleep(2000);
thread::sleep(200);
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)
thread::sleep(2000);
thread::sleep(200);
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.
//
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.h:32
Represents a thread synchronization event that, when signaled, resets automatically after releasing a...
Definition auto_reset_event.h:34
virtual bool wait_one()
Blocks the current thread until the current xtd::threading::wait_handle receives a signal.
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.h:85
The example defines a variable, num_ops, that defines the number of threads that will attempt to access the resource. The application thread calls the xtd::threading::thread_pool::queue_user_work_item method for synchronized and unsynchronized access five times each. The xtd::threading::thread_pool::queue_user_work_item method has a single parameter, a delegate that accepts no parameters and returns no value. For synchronized access, it invokes the sync_update_resource method; for unsynchronized access, it invokes the un_sync_update_resource method. After each set of method calls, the application thread calls the xtd::thrrading::auto_reset_event::wait_one method so that it blocks until the xtd::threading::auto_reset_event instance is signaled.

Each call to the sync_update_resource method calls the sync_resource::access method and then calls the xtd::threading::interlocked::decrement method to decrement the num_ops counter. The xtd::threading::interlocked::decrement method Is used to decrement the counter, because otherwise you cannot be certain that a second thread will access the value before a first thread's decremented value has been stored in the variable. When the last synchronized worker thread decrements the counter to zero, indicating that all synchronized threads have completed accessing the resource, the syncUpdate_resource method calls the xtd::threading::event_wait_handle::set method, which signals the main thread to continue execution.

Each call to the un_sync_update_resource method calls the un_syncResource::access method and then calls the xtd::threading::interlocked::decrement method to decrement the num_ops counter. Once again, the xtd::threading::interlocked::decrement method Is used to decrement the counter to ensure that a second thread does not access the value before a first thread's decremented value has been assigned to the variable. When the last unsynchronized worker thread decrements the counter to zero, indicating that no more unsynchronized threads need to access the resource, the un_sync_update_resource method calls the xtd::threading::event_wait_handle::set method, which signals the main thread to continue execution.

As the output from the example shows, synchronized access ensures that the calling thread exits the protected resource before another thread can access it; each thread waits on its predecessor. On the other hand, without the lock, the un_sync_resource::access method is called in the order in which threads reach it.
Remarks
The xtd::threading::monitor class allows you to synchronize access to a region of code by taking and releasing a lock on a particular object by calling the xtd::threading::monitor::enter, xtd::threading::monitor::try_enter, and xtd::threading::monitor::exit methods. Object locks provide the ability to restrict access to a block of code, commonly called a critical section. While a thread owns the lock for an object, no other thread can acquire that lock. You can also use the xtd::threading::monitor class to ensure that no other thread is allowed to access a section of application code being executed by the lock owner, unless the other thread is executing the code using a different locked object. Because the xtd::threading::monotor class has thread affinity, the thread that acquired a lock must release the lock by calling the xtd::threading::monotor::exit method.
The xtd::threading::monitor class: An overview
xtd::threading::monotor has the following features:
  • It is associated with an object on demand.
  • It is unbound, which means it can be called directly from any context.
  • An instance of the xtd::threading::monitor class cannot be created; the methods of the xtd::threading::monitor class are all static. Each method is passed the synchronized object that controls access to the critical section. The following table describes the actions that can be taken by threads that access synchronized objects:
    Action Description
    xtd::threading::monitor::enter, xtd::threading::monitor::try_enter Acquires a lock for an object. This action also marks the beginning of a critical section. No other thread can enter the critical section unless it is executing the instructions in the critical section using a different locked object.
    xtd::threading::monitor::wait Releases the lock on an object in order to permit other threads to lock and access the object. The calling thread waits while another thread accesses the object. xtd::threading::monitor::pulse signals are used to notify waiting threads about changes to an object's state.
    xtd::threading::monitor::pulse, xtd::threading::monitor::pulse_all Sends a signal to one or more waiting threads. The signal notifies a waiting thread that the state of the locked object has changed, and the owner of the lock is ready to release the lock. The waiting thread is placed in the object's ready queue so that it might eventually receive the lock for the object. Once the thread has the lock, it can check the new state of the object to see if the required state has been reached.
    xtd::threading::monitor::exit Releases the lock on an object. This action also marks the end of a critical section protected by the locked object.
    There are two sets of overloads for the xtd::threading::monitor::enter and xtd::threading::monitor::try_enter methods. One set of overloads has a boolean parameter that is atomically set to true if the lock is acquired, even if an exception is thrown when acquiring the lock. Use these overloads if it is critical to release the lock in all cases, even when the resources the lock is protecting might not be in a consistent state.
The lock object
The xtd::threading::monitor class consists of static methods that operate on an object that controls access to the critical section. The following information is maintained for each synchronized object:
  • A reference to the thread that currently holds the lock.
  • A reference to a ready queue, which contains the threads that are ready to obtain the lock.
  • A reference to a waiting queue, which contains the threads that are waiting for notification of a change in the state of the locked object.
The critical section
Use the xtd::threading::monitor::enter and xtd::threading::monitor::exit methods to mark the beginning and end of a critical section.
Note
The functionality provided by the xtd::threading::monitor::enter and xtd::threading::monitor::exit methods is identical to that provided by the xtd::threading::lock_guard object and the lock_ keyword, except that with the xtd class: :threading::lock_guard class and the lock_ keyword, the xtd::threading::monitor::enter method and the xtd::threading::monitor::exit method are always called, even if an exception has occurred.
It is therefore advisable to use the xtd::threading::lock_guard class or the lock_ keyword instead of calling the xtd::threading::monitor::enter and xtd::threading::monitor::exit methods, to ensure that no critical sections remain in the xtd::threading::monitor class.
The folowing code shows the use use of xtd:threading::monitor::enter and xtd:threading::monitor::exit when an exception occured :
// Define the lock object.
auto obj = object {};
try {
// Define the critical section.
// Code to execute one thread at a time.
// Define the end of the critical section.
} catch(...) {
// You also need to define the end of the critical section.
}
static void exit(const object_t &obj)
Releases an exclusive lock on the specified obj.
Definition monitor.h:173
static void enter(const object_t &obj)
Acquires an exclusive lock on the specified obj.
Definition monitor.h:143

The same code with the xtd::threading::lock_guard class :
// Define the lock object.
auto obj = object {};
try {
// Define the critical section.
// Code to execute one thread at a time.
} catch(...) {
}
Provides a mechanism that synchronizes access to objects with xtd::threading::monitor.
Definition lock_guard.h:30

The same code with the lock_ keyword :
// Define the lock object.
auto obj = object {};
try {
// Define the critical section.
lock_(obj) {
// Code to execute one thread at a time.
}
} catch(...) {
}
pulse, pulse_all, and wait
Once a thread owns the lock and has entered the critical section that the lock protects, it can call the xtd::threading::monitor::wait, xtd::threading::monitor::pulse, and xtd::threading::monitor::pulse_all methods.

When the thread that holds the lock calls xtd::threading::monitor::wait, the lock is released and the thread is added to the waiting queue of the synchronized object. The first thread in the ready queue, if any, acquires the lock and enters the critical section. The thread that called Wait is moved from the waiting queue to the ready queue when either the xtd::threading::monitor::pulse or the xtd::threading::monitor::pulse_all method is called by the thread that holds the lock (to be moved, the thread must be at the head of the waiting queue). The xtd::threading::monitor::wait method returns when the calling thread reacquires the lock.

When the thread that holds the lock calls xtd::threading::monitor::pulse, the thread at the head of the waiting queue is moved to the ready queue. The call to the xtd::threading::monitor::pulse_all method moves all the threads from the waiting queue to the ready queue.
Monitors and wait handles
It is important to note the distinction between the use of the xtd::threading::monitor class and xtd::threading::wait_handle objects.
  • The xtd::threading::monitor class is purely managed, fully portable, and might be more efficient in terms of operating-system resource requirements.
  • xtd::threading::wait_handle objects represent operating-system waitable objects, are useful for synchronizing between managed and unmanaged code, and expose some advanced operating-system features like the ability to wait on many objects at once.

Public Static Methods

template<typename object_t >
static void enter (const object_t &obj)
 Acquires an exclusive lock on the specified obj.
 
template<typename object_t >
static void enter (const object_t &obj, bool &lock_taken)
 Acquires an exclusive lock on the specified obj.
 
template<typename object_t >
static void exit (const object_t &obj)
 Releases an exclusive lock on the specified obj.
 
template<typename object_t >
static bool is_entered (const object_t &obj)
 Determines whether the current thread holds the lock on the specified object.
 
template<typename object_t >
static void pulse (const object_t &obj)
 Notifies a thread in the waiting queue of a change in the locked object's state.
 
template<typename object_t >
static void pulse_all (const object_t &obj)
 Notifies all waiting threads of a change in the object's state.
 
template<typename object_t >
static bool try_enter (const object_t &obj) noexcept
 Attempts to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, bool &lock_taken) noexcept
 Attempts to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, int32 milliseconds_timeout) noexcept
 Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, int32 milliseconds_timeout, bool &lock_taken) noexcept
 Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, int64 milliseconds_timeout) noexcept
 Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, int64 milliseconds_timeout, bool &lock_taken) noexcept
 Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, const time_span &timeout) noexcept
 Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool try_enter (const object_t &obj, const time_span &timeout, bool &lock_taken) noexcept
 Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.
 
template<typename object_t >
static bool wait (const object_t &obj, int32 milliseconds_timeout)
 Releases the lock on an object and blocks the current thread until it reacquires the lock. If the specified time-out interval elapses, the thread enters the ready queue.
 
template<typename object_t >
static bool wait (const object_t &obj, const time_span &timeout)
 Releases the lock on an object and blocks the current thread until it reacquires the lock. If the specified time-out interval elapses, the thread enters the ready queue.
 
template<typename object_t >
static bool wait (const object_t &obj)
 Releases the lock on an object and blocks the current thread until it reacquires the lock.
 

Member Function Documentation

◆ enter() [1/2]

template<typename object_t >
static void xtd::threading::monitor::enter ( const object_t &  obj)
inlinestatic

Acquires an exclusive lock on the specified obj.

Parameters
objThe object on which to acquire the monitor lock.
Remarks
Use xtd::threading::monotor::enter to acquire the xtd::threading::monotor on the object passed as the parameter. If another thread has executed an xtd::threading::monotor::enter on the object, but has not yet executed the corresponding xtd::threading::monitor::exit, the current thread will block until the other thread releases the object. It is legal for the same thread to invoke xtd::threading::monotor::enter more than once without it blocking; however, an equal number of xtd::threading::monitor::exit calls must be invoked before other threads waiting on the object will unblock.

◆ enter() [2/2]

template<typename object_t >
static void xtd::threading::monitor::enter ( const object_t &  obj,
bool &  lock_taken 
)
inlinestatic

Acquires an exclusive lock on the specified obj.

Parameters
objThe object on which to acquire the monitor lock.
lock_takenThe result of the attempt to acquire the lock, passed by reference. The input must be false. The output is true if the lock is acquired; otherwise, the output is false. The output is set even if an exception occurs during the attempt to acquire the lock.
Note
If no exception occurs, the output of this method is always true.
Remarks
Use xtd::threading::monotor::enter to acquire the xtd::threading::monotor on the object passed as the parameter. If another thread has executed an xtd::threading::monotor::enter on the object, but has not yet executed the corresponding xtd::threading::monitor::exit, the current thread will block until the other thread releases the object. It is legal for the same thread to invoke xtd::threading::monotor::enter more than once without it blocking; however, an equal number of xtd::threading::monitor::exit calls must be invoked before other threads waiting on the object will unblock.

◆ exit()

template<typename object_t >
static void xtd::threading::monitor::exit ( const object_t &  obj)
inlinestatic

Releases an exclusive lock on the specified obj.

Parameters
objThe object on which to release the lock.
Remarks
The calling thread must own the lock on the obj parameter. If the calling thread owns the lock on the specified object, and has made an equal number of xtd::threading::monitor::exit and xtd::threading::monotor::enter calls for the object, then the lock is released. If the calling thread has not invoked xtd::threading::monitor::exit as many times as xtd::threading::monotor::enter, the lock is not released.
If the lock is released and other threads are in the ready queue for the object, one of the threads acquires the lock. If other threads are in the waiting queue waiting to acquire the lock, they are not automatically moved to the ready queue when the owner of the lock calls xtd::threading::monitor::exit. To move one or more waiting threads into the ready queue, call xtd::threading::monitor::pulse or xtd::threading::monitor::xtd::threading::monitor::pulse_all before invoking xtd::threading::monitor::exit.

◆ is_entered()

template<typename object_t >
static bool xtd::threading::monitor::is_entered ( const object_t &  obj)
inlinestatic

Determines whether the current thread holds the lock on the specified object.

Parameters
objThe object to test.
Returns
true if the current thread holds the lock on obj; otherwise, false.
Remarks
This method works only for locks that are acquired by using the methods of the xtd::threading::monitor class, or the xtd::threading::lock_guard class, or by using the lock_ keyword, which are implemented with xtd::threading::monitor.
Use this method with diagnostic tools, such as the xtd::diagnostics::debug::assert method, to debug locking issues that involve the xtd::threading::monitor class.

◆ pulse()

template<typename object_t >
static void xtd::threading::monitor::pulse ( const object_t &  obj)
inlinestatic

Notifies a thread in the waiting queue of a change in the locked object's state.

Parameters
objThe object a thread is waiting for.
Exceptions
xtd::threading::synchronization_lock_exceptionThe calling thread does not own the lock for the specified object.
Remarks
Only the current owner of the lock can signal a waiting object using xtd::threading::monitor::pulse.
The thread that currently owns the lock on the specified object invokes this method to signal the next thread in line for the lock. Upon receiving the pulse, the waiting thread is moved to the ready queue. When the thread that invoked xtd::threading::monitor::pulse releases the lock, the next thread in the ready queue (which is not necessarily the thread that was pulsed) acquires the lock.
Warning
The xtd::threading::monitor class does not maintain state indicating that the xtd::threading::monitor::pulse method has been called. Thus, if you call xtd::threading::monitor::pulse when no threads are waiting, the next thread that calls xtd::threading::monitor::wait blocks as if xtd::threading::monitor::pulse had never been called. If two threads are using xtd::threading::monitor::pulse and xtd::threading::monitor::wait to interact, this could result in a deadlock. Contrast this with the behavior of the xtd::threading::auto_reset_event class: If you signal an xtd::threading::auto_reset_event by calling its xtd::threading::event_wait_handle::set method, and there are no threads waiting, the xtd::threading::auto_reset_event remains in a signaled state until a thread calls xtd::threading::wait_handle::wait_one, xtd::threading::wait_handle::wait_any, or xtd::threading::wait_handle::wait_all. The xtd::threading::auto_reset_event releases that thread and returns to the unsignaled state.
Remarks
Note that a synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state.
The xtd::threading::monitor::pulse, xtd::threading::monitor::pulse_all, and xtd::threading::monitor::wait methods must be invoked from within a synchronized block of code.
To signal multiple threads, use the xtd::threading::monitor::pulse_all method.

◆ pulse_all()

template<typename object_t >
static void xtd::threading::monitor::pulse_all ( const object_t &  obj)
inlinestatic

Notifies all waiting threads of a change in the object's state.

Parameters
objThe object a thread is waiting for.
Exceptions
xtd::threading::synchronization_lock_exceptionThe calling thread does not own the lock for the specified object.
Remarks
The thread that currently owns the lock on the specified object invokes this method to signal all threads waiting to acquire the lock on the object. After the signal is sent, the waiting threads are moved to the ready queue. When the thread that invoked xtd::threading::monitor::xtd::threading::monitor::pulse_all releases the lock, the next thread in the ready queue acquires the lock.
Note that a synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state.
The xtd::threading::monitor::pulse, xtd::threading::monitor::xtd::threading::monitor::pulse_all, and Wait methods must be invoked from within a synchronized block of code.
The remarks for the xtd::threading::monitor::pulse method explain what happens if xtd::threading::monitor::pulse is called when no threads are waiting.
To signal a single thread, use the xtd::threading::monitor::pulse method.

◆ try_enter() [1/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj)
inlinestaticnoexcept

Attempts to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If successful, this method acquires an exclusive lock on the obj parameter. This method returns immediately, whether or not the lock is available.
This method is similar to xtd::threading::monotor::enter, but it will never block. If the thread cannot enter without blocking, the method returns false, and the thread does not enter the critical section.

◆ try_enter() [2/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
bool &  lock_taken 
)
inlinestaticnoexcept

Attempts to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
lock_takenThe result of the attempt to acquire the lock, passed by reference. The input must be false. The output is true if the lock is acquired; otherwise, the output is false. The output is set even if an exception occurs during the attempt to acquire the lock.
Note
If no exception occurs, the output of this method is always true.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If successful, this method acquires an exclusive lock on the obj parameter. This method returns immediately, whether or not the lock is available.
This method is similar to xtd::threading::monotor::enter, but it will never block. If the thread cannot enter without blocking, the method returns false, and the thread does not enter the critical section.

◆ try_enter() [3/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
const time_span timeout 
)
inlinestaticnoexcept

Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
timeoutA time_span representing the amount of time to wait for the lock. A value of -1 millisecond specifies an infinite wait.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the value of the timeout parameter converted to milliseconds equals -1, this method is equivalent to xtd::threading::monotor::enter. If the value of timeout equals 0, this method is equivalent to try_enter.

◆ try_enter() [4/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
const time_span timeout,
bool &  lock_taken 
)
inlinestaticnoexcept

Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
timeoutA time_span representing the amount of time to wait for the lock. A value of -1 millisecond specifies an infinite wait.
lock_takenThe result of the attempt to acquire the lock, passed by reference. The input must be false. The output is true if the lock is acquired; otherwise, the output is false. The output is set even if an exception occurs during the attempt to acquire the lock.
Note
If no exception occurs, the output of this method is always true.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the value of the timeout parameter converted to milliseconds equals -1, this method is equivalent to xtd::threading::monotor::enter. If the value of timeout equals 0, this method is equivalent to try_enter.

◆ try_enter() [5/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
int32  milliseconds_timeout 
)
inlinestaticnoexcept

Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
milliseconds_timeoutThe number of milliseconds to wait for the lock.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the milliseconds_timeout parameter equals Timeout::Infinite, this method is equivalent to xtd::threading::monotor::enter. If milliseconds_timeout equals 0, this method is equivalent to try_enter.

◆ try_enter() [6/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
int32  milliseconds_timeout,
bool &  lock_taken 
)
inlinestaticnoexcept

Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
milliseconds_timeoutThe number of milliseconds to wait for the lock.
lock_takenThe result of the attempt to acquire the lock, passed by reference. The input must be false. The output is true if the lock is acquired; otherwise, the output is false. The output is set even if an exception occurs during the attempt to acquire the lock.
Note
If no exception occurs, the output of this method is always true.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the milliseconds_timeout parameter equals Timeout::Infinite, this method is equivalent to xtd::threading::monotor::enter. If milliseconds_timeout equals 0, this method is equivalent to try_enter.

◆ try_enter() [7/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
int64  milliseconds_timeout 
)
inlinestaticnoexcept

Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
milliseconds_timeoutThe number of milliseconds to wait for the lock.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the milliseconds_timeout parameter equals Timeout::Infinite, this method is equivalent to xtd::threading::monotor::enter. If milliseconds_timeout equals 0, this method is equivalent to try_enter.

◆ try_enter() [8/8]

template<typename object_t >
static bool xtd::threading::monitor::try_enter ( const object_t &  obj,
int64  milliseconds_timeout,
bool &  lock_taken 
)
inlinestaticnoexcept

Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.

Parameters
objThe object on which to acquire the lock.
milliseconds_timeoutThe number of milliseconds to wait for the lock.
lock_takenThe result of the attempt to acquire the lock, passed by reference. The input must be false. The output is true if the lock is acquired; otherwise, the output is false. The output is set even if an exception occurs during the attempt to acquire the lock.
Note
If no exception occurs, the output of this method is always true.
Returns
bool true if the current thread acquires the lock; otherwise, false
Remarks
If the milliseconds_timeout parameter equals Timeout::Infinite, this method is equivalent to xtd::threading::monotor::enter. If milliseconds_timeout equals 0, this method is equivalent to try_enter.

◆ wait() [1/3]

template<typename object_t >
static bool xtd::threading::monitor::wait ( const object_t &  obj)
inlinestatic

Releases the lock on an object and blocks the current thread until it reacquires the lock.

Parameters
objThe object on which to wait.
Returns
true if the call returned because the caller reacquired the lock for the specified object. This method does not return if the lock is not reacquired.
Exceptions
xtd::threading::synchronization_lock_exceptionxtd::threading::monitor::wait is not invoked from within a synchronized block of code.
Remarks
This method does not return until it reacquires an exclusive lock on the obj parameter.
The thread that currently owns the lock on the specified object invokes this method in order to release the object so that another thread can access it. The caller is blocked while waiting to reacquire the lock. This method is called when the caller needs to wait for a state change that will occur as a result of another thread's operations.
The time-out ensures that the current thread does not block indefinitely if another thread releases the lock without first calling the xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method. It also moves the thread to the ready queue, bypassing other threads ahead of it in the wait queue, so that it can reacquire the lock sooner. The thread can test the return value of the xtd::threading::monitor::wait method to determine whether it reacquired the lock prior to the time-out. The thread can evaluate the conditions that caused it to enter the wait, and if necessary call the xtd::threading::monitor::wait method again.
When a thread calls xtd::threading::monitor::wait, it releases the lock and enters the waiting queue. At this point, the next thread in the ready queue (if there is one) is allowed to take control of the lock. The thread that invoked Wait remains in the waiting queue until either a thread that holds the lock invokes xtd::threading::monitor::pulse_all, or it is the next in the queue and a thread that holds the lock invokes xtd::threading::monitor::pulse. However, if milliseconds_timeout elapses before another thread invokes this object's xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method, the original thread is moved to the ready queue in order to regain the lock.
Note
If xtd::threading::timeout::infinite is specified for the milliseconds_timeout parameter, this method blocks indefinitely unless the holder of the lock calls xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all. If milliseconds_timeout equals 0, the thread that calls Wait releases the lock and then immediately enters the ready queue in order to regain the lock.
Remarks
The caller executes xtd::threading::monitor::wait once, regardless of the number of times xtd::threading::monitor::enter has been invoked for the specified object. Conceptually, the Wait method stores the number of times the caller invoked xtd::threading::monitor::enter on the object and invokes xtd::threading::monitor::exit as many times as necessary to fully release the locked object. The caller then blocks while waiting to reacquire the object. When the caller reacquires the lock, the system calls xtd::threading::monitor::enter as many times as necessary to restore the saved xtd::threading::monitor::enter count for the caller. Calling xtd::threading::monitor::wait releases the lock for the specified object only; if the caller is the owner of locks on other objects, these locks are not released.
Note
A synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state.
Remarks
The xtd::threading::monitor::pulse, xtd::threading::monitor::pulse_all, and Wait methods must be invoked from within a synchronized block of code.
The remarks for the xtd::threading::monitor::pulse method explain what happens if xtd::threading::monitor::pulse is called when no threads are waiting.

◆ wait() [2/3]

template<typename object_t >
static bool xtd::threading::monitor::wait ( const object_t &  obj,
const time_span timeout 
)
inlinestatic

Releases the lock on an object and blocks the current thread until it reacquires the lock. If the specified time-out interval elapses, the thread enters the ready queue.

Parameters
objThe object on which to wait.
timeoutA xtd::time_span representing the amount of time to wait before the thread enters the ready queue.
Returns
true if the lock was reacquired before the specified time elapsed; false if the lock was reacquired after the specified time elapsed. The method does not return until the lock is reacquired.
Exceptions
xtd::threading::synchronization_lock_exceptionxtd::threading::monitor::wait is not invoked from within a synchronized block of code.
Remarks
This method does not return until it reacquires an exclusive lock on the obj parameter.
The thread that currently owns the lock on the specified object invokes this method in order to release the object so that another thread can access it. The caller is blocked while waiting to reacquire the lock. This method is called when the caller needs to wait for a state change that will occur as a result of another thread's operations.
The time-out ensures that the current thread does not block indefinitely if another thread releases the lock without first calling the xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method. It also moves the thread to the ready queue, bypassing other threads ahead of it in the wait queue, so that it can reacquire the lock sooner. The thread can test the return value of the xtd::threading::monitor::wait method to determine whether it reacquired the lock prior to the time-out. The thread can evaluate the conditions that caused it to enter the wait, and if necessary call the xtd::threading::monitor::wait method again.
When a thread calls xtd::threading::monitor::wait, it releases the lock and enters the waiting queue. At this point, the next thread in the ready queue (if there is one) is allowed to take control of the lock. The thread that invoked Wait remains in the waiting queue until either a thread that holds the lock invokes xtd::threading::monitor::pulse_all, or it is the next in the queue and a thread that holds the lock invokes xtd::threading::monitor::pulse. However, if milliseconds_timeout elapses before another thread invokes this object's xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method, the original thread is moved to the ready queue in order to regain the lock.
Note
If xtd::threading::timeout::infinite is specified for the milliseconds_timeout parameter, this method blocks indefinitely unless the holder of the lock calls xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all. If milliseconds_timeout equals 0, the thread that calls Wait releases the lock and then immediately enters the ready queue in order to regain the lock.
Remarks
The caller executes xtd::threading::monitor::wait once, regardless of the number of times xtd::threading::monitor::enter has been invoked for the specified object. Conceptually, the Wait method stores the number of times the caller invoked xtd::threading::monitor::enter on the object and invokes xtd::threading::monitor::exit as many times as necessary to fully release the locked object. The caller then blocks while waiting to reacquire the object. When the caller reacquires the lock, the system calls xtd::threading::monitor::enter as many times as necessary to restore the saved xtd::threading::monitor::enter count for the caller. Calling xtd::threading::monitor::wait releases the lock for the specified object only; if the caller is the owner of locks on other objects, these locks are not released.
Note
A synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state.
Remarks
The xtd::threading::monitor::pulse, xtd::threading::monitor::pulse_all, and Wait methods must be invoked from within a synchronized block of code.
The remarks for the xtd::threading::monitor::pulse method explain what happens if xtd::threading::monitor::pulse is called when no threads are waiting.

◆ wait() [3/3]

template<typename object_t >
static bool xtd::threading::monitor::wait ( const object_t &  obj,
int32  milliseconds_timeout 
)
inlinestatic

Releases the lock on an object and blocks the current thread until it reacquires the lock. If the specified time-out interval elapses, the thread enters the ready queue.

Parameters
objThe object on which to wait.
milliseconds_timeoutThe number of milliseconds to wait before the thread enters the ready queue.
Returns
true if the lock was reacquired before the specified time elapsed; false if the lock was reacquired after the specified time elapsed. The method does not return until the lock is reacquired.
Exceptions
xtd::threading::synchronization_lock_exceptionxtd::threading::monitor::wait is not invoked from within a synchronized block of code.
Remarks
This method does not return until it reacquires an exclusive lock on the obj parameter.
The thread that currently owns the lock on the specified object invokes this method in order to release the object so that another thread can access it. The caller is blocked while waiting to reacquire the lock. This method is called when the caller needs to wait for a state change that will occur as a result of another thread's operations.
The time-out ensures that the current thread does not block indefinitely if another thread releases the lock without first calling the xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method. It also moves the thread to the ready queue, bypassing other threads ahead of it in the wait queue, so that it can reacquire the lock sooner. The thread can test the return value of the xtd::threading::monitor::wait method to determine whether it reacquired the lock prior to the time-out. The thread can evaluate the conditions that caused it to enter the wait, and if necessary call the xtd::threading::monitor::wait method again.
When a thread calls xtd::threading::monitor::wait, it releases the lock and enters the waiting queue. At this point, the next thread in the ready queue (if there is one) is allowed to take control of the lock. The thread that invoked Wait remains in the waiting queue until either a thread that holds the lock invokes xtd::threading::monitor::pulse_all, or it is the next in the queue and a thread that holds the lock invokes xtd::threading::monitor::pulse. However, if milliseconds_timeout elapses before another thread invokes this object's xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all method, the original thread is moved to the ready queue in order to regain the lock.
Note
If xtd::threading::timeout::infinite is specified for the milliseconds_timeout parameter, this method blocks indefinitely unless the holder of the lock calls xtd::threading::monitor::pulse or xtd::threading::monitor::pulse_all. If milliseconds_timeout equals 0, the thread that calls Wait releases the lock and then immediately enters the ready queue in order to regain the lock.
Remarks
The caller executes xtd::threading::monitor::wait once, regardless of the number of times xtd::threading::monitor::enter has been invoked for the specified object. Conceptually, the Wait method stores the number of times the caller invoked xtd::threading::monitor::enter on the object and invokes xtd::threading::monitor::exit as many times as necessary to fully release the locked object. The caller then blocks while waiting to reacquire the object. When the caller reacquires the lock, the system calls xtd::threading::monitor::enter as many times as necessary to restore the saved xtd::threading::monitor::enter count for the caller. Calling xtd::threading::monitor::wait releases the lock for the specified object only; if the caller is the owner of locks on other objects, these locks are not released.
Note
A synchronized object holds several references, including a reference to the thread that currently holds the lock, a reference to the ready queue, which contains the threads that are ready to obtain the lock, and a reference to the waiting queue, which contains the threads that are waiting for notification of a change in the object's state.
Remarks
The xtd::threading::monitor::pulse, xtd::threading::monitor::pulse_all, and Wait methods must be invoked from within a synchronized block of code.
The remarks for the xtd::threading::monitor::pulse method explain what happens if xtd::threading::monitor::pulse is called when no threads are waiting.

The documentation for this class was generated from the following file: