lock 类
此类自动获取锁,以便同步多个线程对一个对象的访问。 构造类时,类会获取锁,销毁类时,类会释放锁。
语法
ref class lock;
备注
lock
仅适用于 CLR 对象,并且只能在 CLR 代码中使用。
在内部,lock 类使用 Monitor 同步访问。 有关详细信息,请参阅参考文章。
成员
公共构造函数
名称 | 描述 |
---|---|
lock::lock | 构造 lock 对象,可以选择永远等待获取锁,选择在指定时间内等待获取锁,也可以选择立即获取锁。 |
lock::~lock | 构造 lock 对象。 |
公共方法
名称 | 描述 |
---|---|
lock::acquire | 获取对象上的锁,可以选择永远等待获取锁,选择在指定时间内等待获取锁,也可以选择立即获取锁。 |
lock::is_locked | 指示是否保留锁。 |
lock::release | 释放锁。 |
lock::try_acquire | 获取对象上的锁,等待指定的时间并返回 bool ,报告成功获取锁而不是引发异常。 |
公共运算符
“属性” | 描述 |
---|---|
lock::operator bool | 用于在条件表达式中使用 lock 的运算符。 |
lock::operator== | 相等运算符。 |
lock::operator!= | 不等运算符。 |
要求
头文件 <msclr\lock.h>
命名空间 msclr
lock::lock
构造 lock
对象,可以选择永远等待获取锁,选择在指定时间内等待获取锁,也可以选择立即获取锁。
template<class T> lock(
T ^ _object
);
template<class T> lock(
T ^ _object,
int _timeout
);
template<class T> lock(
T ^ _object,
System::TimeSpan _timeout
);
template<class T> lock(
T ^ _object,
lock_later
);
参数
_object
要锁定的对象。
_timeout
超时值(以毫秒为单位)或为 TimeSpan。
异常
如果在超时之前未获取锁,则引发 ApplicationException。
注解
构造函数的前三种形式尝试在指定的超时时间段(或者如果未指定时间段,则为 Infinite)内获取 _object
上的锁。
构造函数的第四种形式不会获取 _object
上的锁。 lock_later
是 lock_when enum 的成员。 在这种情况下使用 lock::acquire 或 lock::try_acquire 获取锁。
调用析构函数时,将自动释放锁。
_object
不能是 ReaderWriterLock。 如果是,则会导致编译器错误。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 然后,主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_lock.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::~lock
构造 lock
对象。
~lock();
备注
析构函数调用 lock::release。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 然后,主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_dtor.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::acquire
获取对象上的锁,可以选择永远等待获取锁,选择在指定时间内等待获取锁,也可以选择立即获取锁。
void acquire();
void acquire(
int _timeout
);
void acquire(
System::TimeSpan _timeout
);
参数
_timeout
超时值(以毫秒为单位)或为 TimeSpan。
异常
如果在超时之前未获取锁,则引发 ApplicationException。
备注
如果未提供超时值,则默认超时为 Infinite。
如果已获取锁,则此函数不执行任何操作。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 然后,主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_acquire.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::is_locked
指示是否保留锁。
bool is_locked();
返回值
如果保留锁,则为 true
,否则为 false
。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁定,以定期检查是否存在任何工作线程,并等待退出,直到所有工作线程都已完成其任务。
// msl_lock_is_locked.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
l.try_acquire(50); // try to acquire lock, don't throw an exception if can't
if (l.is_locked()) { // check if we got the lock
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::operator bool
用于在条件表达式中使用 lock
的运算符。
operator bool();
返回值
如果保留锁,则为 true
,否则为 false
。
备注
此运算符实际上转换为比 bool
更安全的 _detail_class::_safe_bool
,因为它不能转换为整数类型。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_op_bool.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
l.try_acquire(50); // try to acquire lock, don't throw an exception if can't
if (l) { // use bool operator to check for lock
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::release
释放锁。
void release();
注解
如果未保留锁,release
不会执行任何操作。
无需显式调用此函数。 当 lock
对象超出范围时,其析构函数调用 release
。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 然后,主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_release.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::try_acquire
获取对象上的锁,等待指定的时间并返回 bool
,报告成功获取锁而不是引发异常。
bool try_acquire(
int _timeout_ms
);
bool try_acquire(
System::TimeSpan _timeout
);
参数
_timeout
超时值(以毫秒为单位)或为 TimeSpan。
返回值
如果已获得锁,则为 true
,否则为 false
。
备注
如果已获取锁,则此函数不执行任何操作。
示例
此示例跨几个线程使用类的单个实例。 该类对自身使用锁,以确保对其内部数据的访问对于每个线程都是一致的。 主应用程序线程对该类的相同实例使用锁,以定期检查是否存在任何工作线程。 然后,主应用程序会等待退出,直到所有工作线程都已完成其任务。
// msl_lock_try_acquire.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
ref class CounterClass {
private:
int Counter;
public:
property int ThreadCount;
// function called by multiple threads, use lock to keep Counter consistent
// for each thread
void UseCounter() {
try {
lock l(this); // wait infinitely
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
for (int i = 0; i < 10; i++) {
Counter++;
Thread::Sleep(10);
}
Console::WriteLine("In thread {0}, Counter = {1}", Thread::CurrentThread->ManagedThreadId,
Counter);
Counter = 0;
// lock is automatically released when it goes out of scope and its destructor is called
}
catch (...) {
Console::WriteLine("Couldn't acquire lock!");
}
ThreadCount--;
}
};
int main() {
// create a few threads to contend for access to the shared data
CounterClass^ cc = gcnew CounterClass;
array<Thread^>^ tarr = gcnew array<Thread^>(5);
ThreadStart^ startDelegate = gcnew ThreadStart(cc, &CounterClass::UseCounter);
for (int i = 0; i < tarr->Length; i++) {
tarr[i] = gcnew Thread(startDelegate);
cc->ThreadCount++;
tarr[i]->Start();
}
// keep our main thread alive until all worker threads have completed
lock l(cc, lock_later); // don't lock now, just create the object
while (true) {
if (l.try_acquire(50)) { // try to acquire lock, don't throw an exception if can't
if (0 == cc->ThreadCount) {
Console::WriteLine("All threads completed.");
break; // all threads are gone, exit while
}
else {
Console::WriteLine("{0} threads exist, continue waiting...", cc->ThreadCount);
l.release(); // some threads exist, let them do their work
}
}
}
}
In thread 3, Counter = 0
In thread 3, Counter = 10
In thread 5, Counter = 0
In thread 5, Counter = 10
In thread 7, Counter = 0
In thread 7, Counter = 10
In thread 4, Counter = 0
In thread 4, Counter = 10
In thread 6, Counter = 0
In thread 6, Counter = 10
All threads completed.
lock::operator==
相等运算符。
template<class T> bool operator==(
T t
);
参数
t
要用于比较是否相等的对象。
返回值
如果 t
与锁的对象相同,则返回 true
;否则返回 false
。
示例
// msl_lock_op_eq.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
int main () {
Object^ o1 = gcnew Object;
lock l1(o1);
if (l1 == o1) {
Console::WriteLine("Equal!");
}
}
Equal!
lock::operator!=
不等运算符。
template<class T> bool operator!=(
T t
);
参数
t
要比较不等性的对象。
返回值
如果 t
与锁的对象不同,则返回 true
;否则返回 false
。
示例
// msl_lock_op_ineq.cpp
// compile with: /clr
#include <msclr/lock.h>
using namespace System;
using namespace System::Threading;
using namespace msclr;
int main () {
Object^ o1 = gcnew Object;
Object^ o2 = gcnew Object;
lock l1(o1);
if (l1 != o2) {
Console::WriteLine("Inequal!");
}
}
Inequal!