lock – třída
Tato třída automatizuje uzamčení pro synchronizaci přístupu k objektu z několika vláken. Když ho zkonstruuje, získá zámek a když ho zničí, uvolní zámek.
Syntaxe
ref class lock;
Poznámky
lock
je k dispozici pouze pro objekty CLR a lze ho použít pouze v kódu CLR.
Třída zámku interně používá Monitor k synchronizaci přístupu. Další informace najdete v odkazovaném článku.
Členové
Veřejné konstruktory
Název | Popis |
---|---|
lock::lock | lock Vytvoří objekt, volitelně čeká na získání zámku navždy, po určitou dobu nebo vůbec. |
lock::~lock | Destrukuje lock objekt. |
Veřejné metody
Název | Popis |
---|---|
lock::acquire | Získá zámek objektu, volitelně čeká na získání zámku navždy, po určitou dobu nebo vůbec. |
lock::is_locked | Určuje, jestli se zámek uchovává. |
lock::release | Uvolní zámek. |
lock::try_acquire | Získá zámek objektu, čeká na určitou dobu a vrátí bool zprávu o úspěšném získání místo vyvolání výjimky. |
Veřejné operátory
Název | Popis |
---|---|
lock::operator bool | Operátor pro použití lock v podmíněném výrazu |
lock::operator== | Operátor rovnosti. |
lock::operator!= | Operátor nerovnosti. |
Požadavky
Hlavičkový soubor<msclr\lock.h>
Obor názvů msclr
lock::lock
lock
Vytvoří objekt, volitelně čeká na získání zámku navždy, po určitou dobu nebo vůbec.
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
);
Parametry
_objekt
Objekt, který se má uzamknout.
_přerušení zápasu
Hodnota časového limitu v milisekundách nebo jako TimeSpanhodnota .
Výjimky
ApplicationException Vyvolá výjimku, pokud k získání zámku nedojde před vypršením časového limitu.
Poznámky
První tři formy konstruktoru se pokusí získat zámek _object
v zadaném časovém limitu (nebo Infinite pokud není zadán žádný).
Čtvrtá forma konstruktoru nezíská zámek _object
. lock_later
je členem lock_when výčtu. Zámek můžete získat v tomto případě pomocí zámku::acquire nebo lock::try_acquire .
Zámek se automaticky uvolní při zavolání destruktoru.
_object
nemůže být ReaderWriterLock. Pokud ano, dojde k chybě kompilátoru.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace pak čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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
Destrukuje lock
objekt.
~lock();
Poznámky
Destruktor volá lock::release.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace pak čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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
Získá zámek objektu, volitelně čeká na získání zámku navždy, po určitou dobu nebo vůbec.
void acquire();
void acquire(
int _timeout
);
void acquire(
System::TimeSpan _timeout
);
Parametry
_přerušení zápasu
Hodnota časového limitu v milisekundách nebo jako TimeSpanhodnota .
Výjimky
ApplicationException Vyvolá výjimku, pokud k získání zámku nedojde před vypršením časového limitu.
Poznámky
Pokud není zadána hodnota časového limitu, je výchozí časový limit Infinite.
Pokud už zámek byl získán, tato funkce nic nedělá.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace pak čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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
Určuje, jestli se zámek uchovává.
bool is_locked();
Vrácená hodnota
true
je-li zámek držen, false
jinak.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek na stejné instanci třídy, aby pravidelně kontrolovaly, zda existují nějaká pracovní vlákna, a čeká na ukončení, dokud všechna pracovní vlákna nedokončí své úkoly.
// 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
Operátor pro použití lock
v podmíněném výrazu
operator bool();
Vrácená hodnota
true
je-li zámek držen, false
jinak.
Poznámky
Tento operátor ve skutečnosti převede, na _detail_class::_safe_bool
který je bezpečnější než bool
proto, že jej nelze převést na celočíselný typ.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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
Uvolní zámek.
void release();
Poznámky
Pokud se neudržuje žádný zámek, release
nic nedělá.
Tuto funkci nemusíte volat explicitně. lock
Když objekt zmizí z oboru, jeho destruktoru volá release
.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace pak čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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
Získá zámek objektu, čeká na určitou dobu a vrátí bool
zprávu o úspěšném získání místo vyvolání výjimky.
bool try_acquire(
int _timeout_ms
);
bool try_acquire(
System::TimeSpan _timeout
);
Parametry
_přerušení zápasu
Hodnota časového limitu v milisekundách nebo jako TimeSpanhodnota .
Vrácená hodnota
true
pokud byl zámek získán, false
jinak.
Poznámky
Pokud už zámek byl získán, tato funkce nic nedělá.
Příklad
Tento příklad používá jednu instanci třídy napříč několika vlákny. Třída používá zámek na sebe, aby se zajistilo, že přístup k interním datům je konzistentní pro každé vlákno. Hlavní vlákno aplikace používá zámek ve stejné instanci třídy k pravidelné kontrole, zda existují nějaká pracovní vlákna. Hlavní aplikace pak čeká na ukončení, dokud všechny pracovní vlákna nedokončí své úkoly.
// 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==
Operátor rovnosti.
template<class T> bool operator==(
T t
);
Parametry
t
Objekt, který se má porovnat s rovností.
Vrácená hodnota
Vrátí true
hodnotu, pokud t
je stejná jako objekt zámku, false
jinak.
Příklad
// 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!=
Operátor nerovnosti.
template<class T> bool operator!=(
T t
);
Parametry
t
Objekt, který se má porovnat s nerovností.
Vrácená hodnota
Vrátí true
, pokud t
se liší od objektu zámku, false
jinak.
Příklad
// 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!