Semaphore.Release Method

Definition

退出信号量。Exits the semaphore.

Overloads

Release()

退出信号量并返回前一个计数。Exits the semaphore and returns the previous count.

Release(Int32)

以指定的次数退出信号量并返回前一个计数。Exits the semaphore a specified number of times and returns the previous count.

Release()

退出信号量并返回前一个计数。Exits the semaphore and returns the previous count.

public:
 int Release();
public int Release ();
member this.Release : unit -> int
Public Function Release () As Integer

Returns

Int32

调用 Release 方法前信号量的计数。The count on the semaphore before the Release method was called.

Exceptions

信号量计数已是最大值。The semaphore count is already at the maximum value.

发生已命名信号量的 Win32 错误。A Win32 error occurred with a named semaphore.

当前信号量表示一个已命名的系统信号量,但用户不具备 ModifyThe current semaphore represents a named system semaphore, but the user does not have Modify.

- 或 --or- 当前信号量表示一个已命名的系统信号量,但它未用 Modify 打开。The current semaphore represents a named system semaphore, but it was not opened with Modify.

Examples

下面的代码示例创建一个信号量,其最大计数为3,初始计数为零。The following code example creates a semaphore with a maximum count of three and an initial count of zero. 该示例启动五个线程,这会阻止等待信号量。The example starts five threads, which block waiting for the semaphore. 主线程使用 Release(Int32) 方法重载将信号量计数增加到其最大值,从而允许三个线程进入信号量。The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. 每个线程使用 Thread.Sleep 方法来等待一秒,模拟工作,然后调用 Release() 方法重载以释放信号量。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.

每次释放信号灯时,都将显示以前的信号量计数。Each time the semaphore is released, the previous semaphore count is displayed. 控制台消息跟踪信号量使用。Console messages track semaphore use. 每个线程的模拟工作时间间隔略有增加,使输出更易于读取。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

Remarks

线程通常使用 WaitOne 方法进入信号量,并且通常使用此方法重载来退出。Threads typically use the WaitOne method to enter the semaphore, and they typically use this method overload to exit.

如果 Release 方法引发 SemaphoreFullException,则不一定表示调用线程出现问题。If a SemaphoreFullException is thrown by the Release method, it does not necessarily indicate a problem with the calling thread. 其他线程中的编程错误可能导致该线程退出信号量的次数超过了输入的时间。A programming error in another thread might have caused that thread to exit the semaphore more times than it entered.

如果当前 Semaphore 对象表示一个已命名的系统信号量,则用户必须具有 SemaphoreRights.Modify 权限,并且必须使用 SemaphoreRights.Modify 权限打开该信号量。If the current Semaphore object represents a named system semaphore, the user must have SemaphoreRights.Modify rights and the semaphore must have been opened with SemaphoreRights.Modify rights.

See also

Release(Int32)

以指定的次数退出信号量并返回前一个计数。Exits the semaphore a specified number of times and returns the previous count.

public:
 int Release(int releaseCount);
public int Release (int releaseCount);
member this.Release : int -> int
Public Function Release (releaseCount As Integer) As Integer

Parameters

releaseCount
Int32

退出信号量的次数。The number of times to exit the semaphore.

Returns

Int32

调用 Release 方法前信号量的计数。The count on the semaphore before the Release method was called.

Exceptions

releaseCount 小于 1。releaseCount is less than 1.

信号量计数已是最大值。The semaphore count is already at the maximum value.

发生已命名信号量的 Win32 错误。A Win32 error occurred with a named semaphore.

当前信号量表示一个已命名的系统信号量,但用户不具备 Modify 权限。The current semaphore represents a named system semaphore, but the user does not have Modify rights.

- 或 --or- 当前信号量表示一个已命名的系统信号量,但它不是以 Modify 权限打开的。The current semaphore represents a named system semaphore, but it was not opened with Modify rights.

Examples

下面的代码示例创建一个信号量,其最大计数为3,初始计数为零。The following code example creates a semaphore with a maximum count of three and an initial count of zero. 该示例启动五个线程,这会阻止等待信号量。The example starts five threads, which block waiting for the semaphore. 主线程使用 Release(Int32) 方法重载将信号量计数增加到其最大值,从而允许三个线程进入信号量。The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. 每个线程使用 Thread.Sleep 方法来等待一秒,模拟工作,然后调用 Release() 方法重载以释放信号量。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.

每次释放信号灯时,都将显示以前的信号量计数。Each time the semaphore is released, the previous semaphore count is displayed. 控制台消息跟踪信号量使用。Console messages track semaphore use. 每个线程的模拟工作时间间隔略有增加,使输出更易于读取。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

Remarks

如果某个线程多次进入了信号量,此方法重载允许使用一次调用来还原整个信号量计数。If a thread has entered the semaphore multiple times, this method overload allows the entire semaphore count to be restored with one call.

如果 Release 方法引发 SemaphoreFullException,则不一定表示调用线程出现问题。If a SemaphoreFullException is thrown by the Release method, it does not necessarily indicate a problem with the calling thread. 其他线程中的编程错误可能导致该线程退出信号量的次数超过了输入的时间。A programming error in another thread might have caused that thread to exit the semaphore more times than it entered.

如果当前 Semaphore 对象表示一个已命名的系统信号量,则用户必须具有 SemaphoreRights.Modify 权限,并且必须使用 SemaphoreRights.Modify 权限打开该信号量。If the current Semaphore object represents a named system semaphore, the user must have SemaphoreRights.Modify rights and the semaphore must have been opened with SemaphoreRights.Modify rights.

See also

Applies to