Semaphore Třída

Definice

Omezuje počet vláken, která mají souběžný přístup k prostředku nebo fondu prostředků.Limits the number of threads that can access a resource or pool of resources concurrently.

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
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 nula.The following code example creates a semaphore with a maximum count of three and an initial count of zero. V příkladu se spustí pět vláken, která blokují čekání na semafor.The example starts five threads, which block waiting for the semaphore. Hlavní vlákno používá přetížení metody Release(Int32) k zvýšení počtu semaforu na maximum, což umožňuje tři vlákna zadat semafor.The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. Každé vlákno používá metodu Thread.Sleep k čekání na jednu sekundu, pro simulaci práce a pak zavolá přetížení metody Release() k uvolnění semaforu.Each thread uses the Thread.Sleep method to wait for one second, to simulate work, and then calls the Release() method overload to release the semaphore. Pokaždé, když je vydaný semafor vydaný, se zobrazí předchozí počet semaforů.Each time the semaphore is released, the previous semaphore count is displayed. Zprávy konzoly sledují použití semaforu.Console messages track semaphore use. Simulovaný interval je mírně zvýšen pro každé vlákno, aby bylo možné výstup snadněji přečíst.The simulated work interval is increased slightly for each thread, to make the output easier to read.

#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(0, 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(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

Pro řízení přístupu k fondu prostředků použijte třídu Semaphore.Use the Semaphore class to control access to a pool of resources. Vlákna vstupují semafor voláním metody WaitOne, která je zděděna z třídy WaitHandle a uvolněte semafor voláním metody Release.Threads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, and release the semaphore by calling the Release method.

Počet u semaforu se snižuje pokaždé, když vlákno vstoupí do semaforu a zvyšuje se, když vlákno uvolní semafor.The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. Pokud je počet nula, následné požadavky budou zablokovány, dokud jiná vlákna neuvolní semafor.When the count is zero, subsequent requests block until other threads release the semaphore. Když všechna vlákna vystavila semafor, je počet na maximální hodnotu zadanou při vytvoření semaforu.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

Neexistuje žádné zaručené pořadí, jako je například FIFO nebo LIFO, ve kterém jsou blokovaná vlákna vstupem do semaforu.There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

Vlákno může semafor zadat víckrát, voláním metody WaitOne opakovaně.A thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. Chcete-li uvolnit některé nebo všechny tyto položky, vlákno může volat přetížení metody bez parametrů Release() víckrát, nebo může volat přetížení metody Release(Int32), které určuje počet položek, které mají být vydány.To release some or all of these entries, the thread can call the parameterless Release() method overload multiple times, or it can call the Release(Int32) method overload that specifies the number of entries to be released.

Třída Semaphore nevynutila identitu vlákna u volání WaitOne nebo Release.The Semaphore class does not enforce thread identity on calls to WaitOne or Release. Je zodpovědností programátora, aby se zajistilo, že vlákna neuvolní semafor příliš mnohokrát.It is the programmer's responsibility to ensure that threads do not release the semaphore too many times. Předpokládejme například, že semafor má maximální počet dvou a že vlákno a a vlákno B zadávají semafor.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Pokud chyba programátora v vlákně B způsobí, že by volání Release dvakrát, obě volání budou úspěšná.If a programming error in thread B causes it to call Release twice, both calls succeed. Počet v semaforu je plný a když vlákno A nakonec volá Release, je vyvolána SemaphoreFullException.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

Semafory mají dva typy: místní semafory a pojmenované systémové semafory.Semaphores are of two types: local semaphores and named system semaphores. Vytvoříte-li objekt Semaphore pomocí konstruktoru, který přijímá název, je přidružen k semaforu s operačním systémem daného názvu.If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. Pojmenované systémové semafory jsou viditelné v celém operačním systému a lze je použít k synchronizaci aktivit procesů.Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. Můžete vytvořit více objektů Semaphore, které reprezentují stejný pojmenovaný semafor systému, a můžete použít metodu OpenExisting k otevření existujícího pojmenovaných systémových semaforů.You can create multiple Semaphore objects that represent the same named system semaphore, and you can use the OpenExisting method to open an existing named system semaphore.

Místní semafor existuje pouze v rámci procesu.A local semaphore exists only within your process. Dá se použít v jakémkoli vlákně v procesu, který má odkaz na místní objekt Semaphore.It can be used by any thread in your process that has a reference to the local Semaphore object. Každý objekt Semaphore je samostatný místní semafor.Each Semaphore object is a separate local semaphore.

Konstruktory

Semaphore(Int32, Int32)

Inicializuje novou instanci třídy Semaphore, zadáním počátečního počtu záznamů a maximálního počtu souběžných položek.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries.

Semaphore(Int32, Int32, String)

Inicializuje novou instanci třídy Semaphore, zadáním počátečního počtu položek a maximálního počtu souběžných položek a volitelně zadáním názvu objektu systémového semaforu.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, and optionally specifying the name of a system semaphore object.

Semaphore(Int32, Int32, String, Boolean)

Inicializuje novou instanci třídy Semaphore, zadáním počátečního počtu položek a maximálního počtu souběžných položek, volitelně zadáním názvu objektu systémového semaforu a zadáním proměnné, která přijímá hodnotu určující, zda byl vytvořen nový systémový semafor.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, and specifying a variable that receives a value indicating whether a new system semaphore was created.

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

Inicializuje novou instanci třídy Semaphore, zadáním počátečního počtu záznamů a maximálního počtu souběžných položek, volitelně zadáním názvu objektu systémového semaforu, zadáním proměnné, která přijímá hodnotu určující, zda byl vytvořen nový systémový semafor, a určíte řízení přístupu zabezpečení pro systémový semafor.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, specifying a variable that receives a value indicating whether a new system semaphore was created, and specifying security access control for the system semaphore.

Pole

WaitTimeout

Indikuje, že vypršel časový limit operace WaitAny(WaitHandle[], Int32, Boolean) předtím, než se nahlásily některé z obslužných rutin čekání.Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. Toto pole je konstantní.This field is constant.

(Zděděno od WaitHandle)

Vlastnosti

Handle

Získá nebo nastaví popisovač nativního operačního systému.Gets or sets the native operating system handle.

(Zděděno od WaitHandle)
SafeWaitHandle

Získá nebo nastaví popisovač nativního operačního systému.Gets or sets the native operating system handle.

(Zděděno od WaitHandle)

Metody

Close()

Uvolní všechny prostředky držené aktuální WaitHandle.Releases all resources held by the current WaitHandle.

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

Vytvoří objekt, který obsahuje všechny relevantní informace požadované pro vygenerování proxy serveru, který se používá ke komunikaci se vzdáleným objektem.Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

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

Uvolní všechny prostředky používané aktuální instancí třídy WaitHandle.Releases all resources used by the current instance of the WaitHandle class.

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

Při přepsání v odvozené třídě uvolní nespravované prostředky používané WaitHandlea volitelně uvolní spravované prostředky.When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

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

Určí, zda se zadaný objekt rovná aktuálnímu objektu.Determines whether the specified object is equal to the current object.

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

Získá zabezpečení řízení přístupu pro pojmenovaný systémový semafor.Gets the access control security for a named system semaphore.

GetHashCode()

Slouží jako výchozí funkce hash.Serves as the default hash function.

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

Načte aktuální objekt služby životnosti, který řídí zásady životního cyklu pro tuto instanci.Retrieves the current lifetime service object that controls the lifetime policy for this instance.

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

Získá Type aktuální instance.Gets the Type of the current instance.

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

Získá objekt služby životnosti, který řídí zásady životního cyklu pro tuto instanci.Obtains a lifetime service object to control the lifetime policy for this instance.

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

Vytvoří kopii aktuálního Objectbez podstruktury.Creates a shallow copy of the current Object.

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

Vytvoří kopii aktuálního objektu MarshalByRefObject bez podstruktury.Creates a shallow copy of the current MarshalByRefObject object.

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

Otevře zadaný pojmenovaný semafor, pokud již existuje.Opens the specified named semaphore, if it already exists.

OpenExisting(String, SemaphoreRights)

Otevře zadaný pojmenovaný semafor, pokud už existuje, s požadovaným přístupem zabezpečení.Opens the specified named semaphore, if it already exists, with the desired security access.

Release()

Ukončí semafor a vrátí předchozí počet.Exits the semaphore and returns the previous count.

Release(Int32)

Ukončí semafor a určí zadaný počet opakování a vrátí předchozí počet.Exits the semaphore a specified number of times and returns the previous count.

SetAccessControl(SemaphoreSecurity)

Nastaví zabezpečení řízení přístupu u pojmenovaných systémových semaforů.Sets the access control security for a named system semaphore.

ToString()

Vrátí řetězec, který představuje aktuální objekt.Returns a string that represents the current object.

(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 byla úspěšná.Opens the specified named semaphore, if it already exists, and returns a value that indicates whether the operation succeeded.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Otevře zadaný pojmenovaný semafor, pokud už existuje, s požadovaným přístupem zabezpečení a vrátí hodnotu, která označuje, jestli operace proběhla úspěšně.Opens the specified named semaphore, if it already exists, with the desired security access, and returns a value that indicates whether the operation succeeded.

WaitOne()

Zablokuje aktuální vlákno, dokud aktuální WaitHandle neobdrží signál.Blocks the current thread until the current WaitHandle receives a signal.

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

Zablokuje aktuální vlákno, dokud aktuální WaitHandle neobdrží signál, pomocí čísla se znaménkem 32, které určuje časový interval v milisekundách.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

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

Zablokuje aktuální vlákno, dokud aktuální WaitHandle neobdrží signál, s použitím 32ého celého čísla se znaménkem k určení časového intervalu a určení, zda se má před čekáním ukončit synchronizující doména.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

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

Zablokuje aktuální vlákno, dokud aktuální instance neobdrží signál, pomocí TimeSpan k určení časového intervalu.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

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

Zablokuje aktuální vlákno, dokud aktuální instance neobdrží signál, pomocí TimeSpan k určení časového intervalu a určení, zda se má před čekáním ukončit synchronizující doména.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(Zděděno od WaitHandle)

Explicitní implementace rozhraní

IDisposable.Dispose()

Uvolní všechny prostředky, které WaitHandlepoužívá.Releases all resources used by the WaitHandle.

(Zděděno od WaitHandle)

Metody rozšíření

GetAccessControl(Semaphore)
SetAccessControl(Semaphore, SemaphoreSecurity)
GetSafeWaitHandle(WaitHandle)

Získá bezpečný popisovač pro zpracování nativního čekání operačního systému.Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Nastaví bezpečný popisovač pro operační systém nativního čekání.Sets a safe handle for a native operating system wait handle.

Platí pro

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

Tento typ je bezpečný pro přístup z více vláken.This type is thread safe.

Viz také