xtd 0.2.0
Loading...
Searching...
No Matches

◆ lock_

#define lock_ (   object)

#include <xtd.core/include/xtd/lock.h>

The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock. The following example includes a lock statement.

class account : public object {
public:
void withdraw(decimal amount) {
lock_ (balance) {
if (amount > balance)
throw exception("Insufficient funds");
balance -= amount;
}
}
private:
decimal balance;
};
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.h:85
long double decimal
Represents a decimal-precision floating-point number.
Definition decimal.h:23

For more information, see Thread Synchronization.

Namespace
xtd
Library
xtd.core
Remarks
The lock_ keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.
The section Threading discusses threading.
The lock_ keyword calls Enter at the start of the block and Exit at the end of the block. A xtd::threading::thread_interrupted_exception is thrown if xtd::threading::thread::interrupt interrupts a thread that is waiting to enter a lock statement.
In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock_ (*this), lock_ (typeof_<my_type>()), and lock_ ("myLock") violate this guideline:
  • lock_ (*this) is a problem if the instance can be accessed publicly.
  • lock_ (typeof_<my_type>()) is a problem if my_type is publicly accessible.
  • lock_ ("my_lock") is a problem because any other code in the process using the same string, will share the same lock.
Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.
You can't use the await_ keyword in the body of a lock_ statement.
Examples
The following sample shows a simple use of threads without locking in C++.
#include <xtd/xtd>
using namespace xtd;
using namespace xtd::rhreading;
class thread_test {
public:
void run_me() {
console::write_line("run_me called");
}
static void main() {
thread_test b;
auto t = thread {thread_start {b, &thread_test::run_me));
t.start();
}
};
startup_(thread_test::main)
// Output: run_me called
#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:175
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10
Examples
The following sample uses threads and lock_. As long as the lock statement is present, the statement block is a critical section and balance will never become a negative number.
#include <xtd/threading/thread_pool>
#include <xtd/console>
#include <xtd/lock>
#include <xtd/random>
#include <xtd/startup>
using namespace xtd;
using namespace xtd::threading;
namespace examples {
class account : public object {
public:
explicit account(int initial) : balance(initial) {}
void do_transactions() {
for (auto i = 0; i < 100; ++i)
withdraw(random.next(1, 100));
}
private:
int withdraw(int amount) {
// This condition never is true unless the lock statement is commented out.
if (balance < 0) throw system_exception {"Negative Balance", csf_};
// Comment out the next line to see the effect of leaving out the lock keyword.
lock_(balance) {
if (balance < amount) return 0;
console::write_line("Balance before Withdrawal : {0}", balance);
console::write_line("Amount to Withdraw : -{0}", amount);
balance = balance - amount;
console::write_line("Balance after Withdrawal : {0}", balance);
return amount;
}
return 0;
}
int balance = 0;
};
class program {
public:
static void main() {
auto account = examples::account {1000};
for (auto i = 0; i < 10; ++i)
thread_pool::queue_user_work_item({account, &account::do_transactions});
thread_pool::close();
}
};
}
startup_(examples::program::main);
// This code can produce the following output :
//
// Balance before Withdrawal : 1000
// Amount to Withdraw : -75
// Balance after Withdrawal : 925
// Balance before Withdrawal : 925
// Amount to Withdraw : -84
// Balance after Withdrawal : 841
// Balance before Withdrawal : 841
// Amount to Withdraw : -69
// Balance after Withdrawal : 772
// Balance before Withdrawal : 772
// Amount to Withdraw : -71
// Balance after Withdrawal : 701
// Balance before Withdrawal : 701
// Amount to Withdraw : -84
// Balance after Withdrawal : 617
// Balance before Withdrawal : 617
// Amount to Withdraw : -81
// Balance after Withdrawal : 536
// Balance before Withdrawal : 536
// Amount to Withdraw : -15
// Balance after Withdrawal : 521
// Balance before Withdrawal : 521
// Amount to Withdraw : -93
// Balance after Withdrawal : 428
// Balance before Withdrawal : 428
// Amount to Withdraw : -6
// Balance after Withdrawal : 422
// Balance before Withdrawal : 422
// Amount to Withdraw : -54
// Balance after Withdrawal : 368
// Balance before Withdrawal : 368
// Amount to Withdraw : -52
// Balance after Withdrawal : 316
// Balance before Withdrawal : 316
// Amount to Withdraw : -67
// Balance after Withdrawal : 249
// Balance before Withdrawal : 249
// Amount to Withdraw : -93
// Balance after Withdrawal : 156
// Balance before Withdrawal : 156
// Amount to Withdraw : -60
// Balance after Withdrawal : 96
// Balance before Withdrawal : 96
// Amount to Withdraw : -7
// Balance after Withdrawal : 89
// Balance before Withdrawal : 89
// Amount to Withdraw : -42
// Balance after Withdrawal : 47
// Balance before Withdrawal : 47
// Amount to Withdraw : -1
// Balance after Withdrawal : 46
// Balance before Withdrawal : 46
// Amount to Withdraw : -22
// Balance after Withdrawal : 24
// Balance before Withdrawal : 24
// Amount to Withdraw : -18
// Balance after Withdrawal : 6
// Balance before Withdrawal : 6
// Amount to Withdraw : -2
// Balance after Withdrawal : 4
// Balance before Withdrawal : 4
// Amount to Withdraw : -2
// Balance after Withdrawal : 2
// Balance before Withdrawal : 2
// Amount to Withdraw : -2
// Balance after Withdrawal : 0
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.h:42
virtual int32 next() const
Returns a nonnegative random number.
Represents a pseudo-random number generator, a device that produces a sequence of numbers that meet c...
Definition random.h:40
The exception that is thrown when a method call is invalid for the object's current state.
Definition system_exception.h:18
#define csf_
Provides information about the current stack frame.
Definition current_stack_frame.h:30
@ i
The I key.
The xtd::threading namespace provides classes and interfaces that enable multithreaded programming....
Definition abandoned_mutex_exception.h:10
Examples
lock.cpp, monitor_lock.cpp, monitor_pulse.cpp, and monitor_pulse_all.cpp.