Semaphore Třída

Definice

Omezuje počet vláken, která můžou současně přistupovat ke zdroji nebo fondu prostředků.

public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
Dědičnost
Semaphore
Dědičnost
Atributy

Příklady

Následující příklad kódu vytvoří semafor s maximálním počtem tří a počátečním počtem nuly. Příklad spustí pět vláken, které blok čekají na semafor. Hlavní vlákno používá Release(Int32) přetížení metody ke zvýšení počtu semaforů na maximum, což umožňuje tři vlákna vstoupit do semaforu. Každé vlákno používá metodu Thread.Sleep k čekání na jednu sekundu, k simulaci práce, a pak voláním Release() přetížení metody uvolnit semafor. Při každém uvolnění semaforu se zobrazí předchozí počet semaforů. Zprávy konzoly sledují použití semaforu. Simulovaný pracovní interval se pro každé vlákno mírně zvýší, aby byl výstup čitelnější.

#using <System.dll>
using namespace System;
using namespace System::Threading;

public ref class Example
{
private:
   // A semaphore that simulates a limited resource pool.
   //
   static Semaphore^ _pool;

   // A padding interval to make the output more orderly.
   static int _padding;

public:
   static void Main()
   {
      // Create a semaphore that can satisfy up to three
      // concurrent requests. Use an initial count of zero,
      // so that the entire semaphore count is initially
      // owned by the main program thread.
      //
      _pool = gcnew Semaphore( 0,3 );
      
      // Create and start five numbered threads.
      //
      for ( int i = 1; i <= 5; i++ )
      {
         Thread^ t = gcnew Thread(
            gcnew ParameterizedThreadStart( Worker ) );
         
         // Start the thread, passing the number.
         //
         t->Start( i );
      }
      
      // Wait for half a second, to allow all the
      // threads to start and to block on the semaphore.
      //
      Thread::Sleep( 500 );
      
      // The main thread starts out holding the entire
      // semaphore count. Calling Release(3) brings the
      // semaphore count back to its maximum value, and
      // allows the waiting threads to enter the semaphore,
      // up to three at a time.
      //
      Console::WriteLine( L"Main thread calls Release(3)." );
      _pool->Release( 3 );

      Console::WriteLine( L"Main thread exits." );
   }

private:
   static void Worker( Object^ num )
   {
      // Each worker thread begins by requesting the
      // semaphore.
      Console::WriteLine( L"Thread {0} begins and waits for the semaphore.", num );
      _pool->WaitOne();
      
      // A padding interval to make the output more orderly.
      int padding = Interlocked::Add( _padding, 100 );

      Console::WriteLine( L"Thread {0} enters the semaphore.", num );
      
      // The thread's "work" consists of sleeping for
      // about a second. Each thread "works" a little
      // longer, just to make the output more orderly.
      //
      Thread::Sleep( 1000 + padding );

      Console::WriteLine( L"Thread {0} releases the semaphore.", num );
      Console::WriteLine( L"Thread {0} previous semaphore count: {1}",
         num, _pool->Release() );
   }
};
using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _pool = new Semaphore(initialCount: 0, maximumCount: 3);

        // Create and start five numbered threads. 
        //
        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        //
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(releaseCount: 3);

        Console.WriteLine("Main thread exits.");
    }

    private static void Worker(object num)
    {
        // Each worker thread begins by requesting the
        // semaphore.
        Console.WriteLine("Thread {0} begins " +
            "and waits for the semaphore.", num);
        _pool.WaitOne();

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
Imports System.Threading

Public Class Example

    ' A semaphore that simulates a limited resource pool.
    '
    Private Shared _pool As Semaphore

    ' A padding interval to make the output more orderly.
    Private Shared _padding As Integer

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a semaphore that can satisfy up to three
        ' concurrent requests. Use an initial count of zero,
        ' so that the entire semaphore count is initially
        ' owned by the main program thread.
        '
        _pool = New Semaphore(0, 3)

        ' Create and start five numbered threads. 
        '
        For i As Integer = 1 To 5
            Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
            'Dim t As New Thread(AddressOf Worker)

            ' Start the thread, passing the number.
            '
            t.Start(i)
        Next i

        ' Wait for half a second, to allow all the
        ' threads to start and to block on the semaphore.
        '
        Thread.Sleep(500)

        ' The main thread starts out holding the entire
        ' semaphore count. Calling Release(3) brings the 
        ' semaphore count back to its maximum value, and
        ' allows the waiting threads to enter the semaphore,
        ' up to three at a time.
        '
        Console.WriteLine("Main thread calls Release(3).")
        _pool.Release(3)

        Console.WriteLine("Main thread exits.")
    End Sub

    Private Shared Sub Worker(ByVal num As Object)
        ' Each worker thread begins by requesting the
        ' semaphore.
        Console.WriteLine("Thread {0} begins " _
            & "and waits for the semaphore.", num)
        _pool.WaitOne()

        ' A padding interval to make the output more orderly.
        Dim padding As Integer = Interlocked.Add(_padding, 100)

        Console.WriteLine("Thread {0} enters the semaphore.", num)
        
        ' The thread's "work" consists of sleeping for 
        ' about a second. Each thread "works" a little 
        ' longer, just to make the output more orderly.
        '
        Thread.Sleep(1000 + padding)

        Console.WriteLine("Thread {0} releases the semaphore.", num)
        Console.WriteLine("Thread {0} previous semaphore count: {1}", _
            num, _
            _pool.Release())
    End Sub
End Class

Poznámky

Semaphore Pomocí třídy můžete řídit přístup k fondu prostředků. Vlákna vstupují do semaforu voláním WaitOne metody, která je zděděna z WaitHandle třídy, a uvolnit semafor voláním Release metody.

Počet na semaforu se sníží pokaždé, když vlákno vstoupí do semaforu, a zvýší se, když vlákno uvolní semafor. Pokud je počet nulový, následné požadavky se zablokují, dokud ostatní vlákna semafor nespustí. Když všechna vlákna uvolní semafor, počet je na maximální hodnotě zadané při vytvoření semaforu.

Neexistuje žádné zaručené pořadí, například FIFO nebo LIFO, ve kterém blokovaná vlákna vstupují do semaforu.

Vlákno může vstoupit do semaforu vícekrát voláním WaitOne metody opakovaně. Chcete-li uvolnit některé nebo všechny tyto položky, vlákno může volat přetížení metody bez Release() parametrů vícekrát, nebo může volat Release(Int32) přetížení metody, které určuje počet položek, které mají být uvolněny.

Třída Semaphore nevynucuje identitu vlákna pro volání WaitOne nebo Release. Je zodpovědností programátora zajistit, aby vlákna neuvolňovat semafor příliš mnohokrát. Předpokládejme například, že semafor má maximální počet dvou a toto vlákno A a vlákno B vstoupí do semaforu. Pokud programovací chyba ve vlákně B způsobí, že se zavolá Release dvakrát, obě volání budou úspěšná. Počet na semaforu je plný a když vlákno A nakonec zavolá Release, SemaphoreFullException vyvolá se .

Semafory jsou dvou typů: místní semafory a pojmenované systémové semafory. Pokud vytvoříte Semaphore objekt pomocí konstruktoru, který přijímá název, je přidružen k semaforu operačního systému tohoto názvu. Pojmenované systémové semafory jsou viditelné v celém operačním systému a lze je použít k synchronizaci aktivit procesů. Můžete vytvořit více Semaphore objektů, které představují stejný pojmenovaný systémový semafor, a můžete použít metodu OpenExisting k otevření existující pojmenované systémové semafor.

Místní semafor existuje pouze v rámci vašeho procesu. Může být použit libovolným vláknem v procesu, které má odkaz na místní Semaphore objekt. Každý Semaphore objekt je samostatný místní semafor.

Upozornění

Ve výchozím nastavení není pojmenovaný semafor omezen na uživatele, který ho vytvořil. Jiní uživatelé mohou být schopni semafor otevřít a používat, včetně narušení semaforu tím, že semafor získá vícekrát a neuvolní ho. Pokud chcete omezit přístup na konkrétní uživatele, můžete při vytváření pojmenovaného semaforu použít přetížení konstruktoru nebo SemaphoreAcl předat SemaphoreSecurity objekt. Vyhněte se používání pojmenovaných semaforů bez omezení přístupu v systémech, které můžou mít nedůvěryhodné uživatele s kódem.

Konstruktory

Semaphore(Int32, Int32)

Inicializuje novou instanci Semaphore třídy s určením počátečního počtu položek a maximálního počtu souběžných položek.

Semaphore(Int32, Int32, String)

Inicializuje novou instanci Semaphore třídy, určuje počáteční počet položek a maximální počet souběžných položek a volitelně určuje název systémového objektu semaforu.

Semaphore(Int32, Int32, String, Boolean)

Inicializuje novou instanci Semaphore třídy, určuje počáteční počet položek a maximální počet souběžných položek, volitelně určuje název objektu systémového semaforu a určuje proměnnou, která přijímá hodnotu označující, zda byl vytvořen nový systémový semafor.

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

Inicializuje novou instanci Semaphore třídy, určuje počáteční počet položek a maximální počet souběžných položek, volitelně určuje název objektu semaforu systému, určuje proměnnou, která obdrží hodnotu označující, zda byl vytvořen nový systémový semafor, a určuje řízení přístupu zabezpečení pro semafor systému.

Pole

WaitTimeout

Označuje, že WaitAny(WaitHandle[], Int32, Boolean) časový limit operace vypršel před signálem některého z popisovačů čekání. Toto pole je konstantní.

(Zděděno od WaitHandle)

Vlastnosti

Handle
Zastaralé.
Zastaralé.

Získá nebo nastaví popisovač nativního operačního systému.

(Zděděno od WaitHandle)
SafeWaitHandle

Získá nebo nastaví popisovač nativního operačního systému.

(Zděděno od WaitHandle)

Metody

Close()

Uvolní všechny prostředky, které má aktuální WaitHandle.

(Zděděno od WaitHandle)
CreateObjRef(Type)

Vytvoří objekt, který obsahuje všechny relevantní informace potřebné k vygenerování proxy používaného ke komunikaci se vzdáleným objektem.

(Zděděno od MarshalByRefObject)
Dispose()

Uvolní všechny prostředky používané aktuální instancí WaitHandle třídy.

(Zděděno od WaitHandle)
Dispose(Boolean)

Při přepsání v odvozené třídě uvolní nespravované prostředky používané WaitHandlenástrojem a volitelně uvolní spravované prostředky.

(Zděděno od WaitHandle)
Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

(Zděděno od Object)
GetAccessControl()

Získá zabezpečení řízení přístupu pro pojmenovaný semafor systému.

GetHashCode()

Slouží jako výchozí hashovací funkce.

(Zděděno od Object)
GetLifetimeService()
Zastaralé.

Načte objekt služby aktuální životnosti, který řídí zásady životnosti pro tuto instanci.

(Zděděno od MarshalByRefObject)
GetType()

Získá aktuální Type instanci.

(Zděděno od Object)
InitializeLifetimeService()
Zastaralé.

Získá objekt služby životnosti, který řídí zásady životnosti pro tuto instanci.

(Zděděno od MarshalByRefObject)
MemberwiseClone()

Vytvoří mělkou kopii aktuálního Objectsouboru .

(Zděděno od Object)
MemberwiseClone(Boolean)

Vytvoří mělkou kopii aktuálního MarshalByRefObject objektu.

(Zděděno od MarshalByRefObject)
OpenExisting(String)

Otevře zadaný pojmenovaný semafor, pokud již existuje.

OpenExisting(String, SemaphoreRights)

Otevře zadaný pojmenovaný semafor, pokud již existuje, s požadovaným přístupem zabezpečení.

Release()

Ukončí semafor a vrátí předchozí počet.

Release(Int32)

Ukončí semafor zadaný počet a vrátí předchozí počet.

SetAccessControl(SemaphoreSecurity)

Nastaví zabezpečení řízení přístupu pro pojmenovaný semafor systému.

ToString()

Vrátí řetězec, který představuje aktuální objekt.

(Zděděno od Object)
TryOpenExisting(String, Semaphore)

Otevře zadaný pojmenovaný semafor, pokud již existuje, a vrátí hodnotu, která označuje, zda operace proběhla úspěšně.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Otevře zadaný pojmenovaný semafor, pokud již existuje, s požadovaným přístupem zabezpečení a vrátí hodnotu, která označuje, zda operace proběhla úspěšně.

WaitOne()

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál.

(Zděděno od WaitHandle)
WaitOne(Int32)

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál, pomocí 32bitového celého čísla se znaménkem určuje časový interval v milisekundách.

(Zděděno od WaitHandle)
WaitOne(Int32, Boolean)

Blokuje aktuální vlákno, dokud proud WaitHandle neobdrží signál. Pomocí 32bitového celého čísla se znaménkem určuje časový interval a určuje, jestli se má před čekáním ukončit synchronizační doména.

(Zděděno od WaitHandle)
WaitOne(TimeSpan)

Blokuje aktuální vlákno, dokud aktuální instance neobdrží signál pomocí parametru TimeSpan pro určení časového intervalu.

(Zděděno od WaitHandle)
WaitOne(TimeSpan, Boolean)

Zablokuje aktuální vlákno, dokud aktuální instance neobdrží signál. Použije TimeSpan k určení časového intervalu a určí, jestli se má před čekáním ukončit synchronizační doména.

(Zděděno od WaitHandle)

Explicitní implementace rozhraní

IDisposable.Dispose()

Toto rozhraní API podporuje produktovou infrastrukturu a není určené k použití přímo z uživatelského kódu.

Uvolní všechny prostředky používané nástrojem WaitHandle.

(Zděděno od WaitHandle)

Metody rozšíření

GetAccessControl(Semaphore)

Vrátí popisovače zabezpečení pro zadaný semaphore.

SetAccessControl(Semaphore, SemaphoreSecurity)

Nastaví popisovače zabezpečení pro zadaný semafor.

GetSafeWaitHandle(WaitHandle)

Získá bezpečný popisovač pro nativní operační systém čekání popisovač.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Nastaví bezpečný popisovač pro čekací úchyt nativního operačního systému.

Platí pro

Bezpečný přístup z více vláken

Tento typ je bezpečný pro přístup z více vláken.

Viz také