Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Essa classe automatiza a obtenção de um bloqueio para sincronizar o acesso a um objeto de vários threads. Quando construída, ela adquire o bloqueio e quando destruída libera o bloqueio.
Sintaxe
ref class lock;
Comentários
lock está disponível apenas para objetos CLR e só pode ser usada em código CLR.
Internamente, a classe lock usa Monitor para sincronizar o acesso. Para obter mais informações, confira o artigo referenciado.
Membros
Construtores públicos
| Nome | Descrição |
|---|---|
| lock::lock | Constrói um objeto lock, opcionalmente esperando para adquirir o bloqueio para sempre, por um período de tempo especificado, ou não. |
| lock::~lock | Destrói um objeto lock. |
Métodos públicos
| Nome | Descrição |
|---|---|
| lock::acquire | Adquire um bloqueio em um objeto, opcionalmente esperando para adquirir o bloqueio para sempre, por um período de tempo especificado, ou não. |
| lock::is_locked | Indica se um bloqueio está sendo mantido. |
| lock::release | Libera um bloqueio. |
| lock::try_acquire | Adquire um bloqueio em um objeto, aguardando um determinado período de tempo e retornando um bool para relatar o sucesso da aquisição em vez de lançar uma exceção. |
Operadores públicos
| Nome | Descrição |
|---|---|
| lock::operator bool | Operador para uso de lock em uma expressão condicional. |
| lock::operator== | Operador de igualdade. |
| lock::operator!= | Operador de desigualdade. |
Requisitos
Arquivo de cabeçalho<msclr\lock.h>
Namespace msclr
lock::lock
Constrói um objeto lock, opcionalmente esperando para adquirir o bloqueio para sempre, por um período de tempo especificado, ou não.
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
);
Parâmetros
_object
O objeto a ser bloqueado.
_timeout
O valor de tempo limite em milissegundos ou como TimeSpan.
Exceções
Gera ApplicationException se a aquisição de bloqueio não ocorrer antes do tempo limite.
Comentários
As três primeiras formas do construtor tentam adquirir um bloqueio em _object dentro do período de tempo limite especificado (ou Infinite se nenhum for especificado).
A quarta forma do construtor não adquire um bloqueio em _object. lock_later é um membro da enumeração lock_when. Use lock::acquire ou lock::try_acquire para adquirir o bloqueio nesse caso.
O bloqueio será liberado automaticamente quando o destruidor for chamado.
_object não pode ser ReaderWriterLock. Se for, ocorrerá um erro do compilador.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. Em seguida, o aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Destrói um objeto lock.
~lock();
Comentários
O destruidor chama lock::release.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. Em seguida, o aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Adquire um bloqueio em um objeto, opcionalmente esperando para adquirir o bloqueio para sempre, por um período de tempo especificado, ou não.
void acquire();
void acquire(
int _timeout
);
void acquire(
System::TimeSpan _timeout
);
Parâmetros
_timeout
O valor de tempo limite em milissegundos ou como TimeSpan.
Exceções
Gera ApplicationException se a aquisição de bloqueio não ocorrer antes do tempo limite.
Comentários
Se um valor de tempo limite não for fornecido, o tempo limite padrão será Infinite.
Se um bloqueio já tiver sido adquirido, essa função não fará nada.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. Em seguida, o aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Indica se um bloqueio está sendo mantido.
bool is_locked();
Valor retornado
true se um bloqueio for mantido, false caso contrário.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread principal do aplicativo usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda há threads de trabalho e aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Operador para uso de lock em uma expressão condicional.
operator bool();
Valor retornado
true se um bloqueio for mantido, false caso contrário.
Comentários
Esse operador é convertido em _detail_class::_safe_bool, que é mais seguro do que bool porque ele não pode ser convertido em um tipo integral.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. O aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Libera um bloqueio.
void release();
Comentários
Se nenhum bloqueio está sendo mantido, release não faz nada.
Você não precisa chamar essa função explicitamente. Quando um objeto lock sai do escopo, seu destruidor chama release.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. Em seguida, o aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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
Adquire um bloqueio em um objeto, aguardando um determinado período de tempo e retornando um bool para relatar o sucesso da aquisição em vez de lançar uma exceção.
bool try_acquire(
int _timeout_ms
);
bool try_acquire(
System::TimeSpan _timeout
);
Parâmetros
_timeout
O valor de tempo limite em milissegundos ou como TimeSpan.
Valor retornado
true se o bloqueio foi adquirido, caso contrário, false.
Comentários
Se um bloqueio já tiver sido adquirido, essa função não fará nada.
Exemplo
Este exemplo usa uma única instância de uma classe em vários threads. A classe usa um bloqueio em si mesma para garantir que os acessos a seus dados internos sejam consistentes para cada thread. O thread do aplicativo principal usa um bloqueio na mesma instância da classe para verificar periodicamente se ainda existem threads de trabalho. Em seguida, o aplicativo principal aguarda para sair até que todos os threads de trabalho tenham concluído suas tarefas.
// 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==
Operador de igualdade.
template<class T> bool operator==(
T t
);
Parâmetros
t
A igualdade de um objeto a ser comparado.
Valor retornado
Retorna true se t for o mesmo que o objeto do bloqueio, caso contrário, false.
Exemplo
// 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!=
Operador de desigualdade.
template<class T> bool operator!=(
T t
);
Parâmetros
t
O objeto a ser comparado quanto à desigualdade.
Valor retornado
Retorna true se t for diferente do objeto do bloqueio, caso contrário, false.
Exemplo
// 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!