Sdílet prostřednictvím


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_laterje č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!