Прочитать на английском

Поделиться через


Semaphore.Release Метод

Определение

Выполняет выход из семафора.

Перегрузки

Release()

Выходит из семафора и возвращает последнее значение счетчика.

Release(Int32)

Выходит из семафора указанное число раз и возвращает последнее значение счетчика.

Release()

Выходит из семафора и возвращает последнее значение счетчика.

public int Release ();

Возвращаемое значение

Int32

Счетчик семафора перед вызовом метода Release.

Исключения

Счетчик семафора уже имеет максимальное значение.

Произошла ошибка Win32, связанная с именованным семафором.

Текущий семафор представляет именованный системный семафор, но пользователь не имеет прав Modify.

-или- Текущий семафор представляет именованный системный семафор, но он не был открыт с правами доступа Modify.

Примеры

В следующем примере кода создается семафор с максимальным числом трех и начальным числом нуля. В примере запускается пять потоков, которые блокируют ожидание семафора. Основной поток использует перегрузку Release(Int32) метода для увеличения числа семафоров до максимального значения, что позволяет трем потокам входить в семафор. Каждый поток использует Thread.Sleep метод для ожидания одной секунды, имитации работы, а затем вызывает 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());
    }
}

Комментарии

Потоки обычно используют WaitOne метод для ввода семафора, и обычно используют эту перегрузку метода для выхода.

Если метод вызывает Release исключениеSemaphoreFullException, оно не обязательно указывает на проблему с вызывающим потоком. Ошибка программирования в другом потоке могла привести к тому, что поток выйдет из семафора больше раз, чем он вошел.

Если текущий Semaphore объект представляет именованный системный семафор, пользователь должен иметь SemaphoreRights.Modify права, а семафор должен быть открыт с SemaphoreRights.Modify правами.

См. также раздел

Применяется к

Release(Int32)

Выходит из семафора указанное число раз и возвращает последнее значение счетчика.

public int Release (int releaseCount);

Параметры

releaseCount
Int32

Количество требуемых выходов из семафора.

Возвращаемое значение

Int32

Счетчик семафора перед вызовом метода Release.

Исключения

Значение параметра releaseCount меньше 1.

Счетчик семафора уже имеет максимальное значение.

Произошла ошибка Win32, связанная с именованным семафором.

Текущий семафор представляет именованный системный семафор, но пользователь не имеет прав Modify.

-или- Текущий семафор представляет именованный системный семафор, но он не был открыт с правами Modify.

Примеры

В следующем примере кода создается семафор с максимальным числом трех и начальным числом нуля. В примере запускается пять потоков, которые блокируют ожидание семафора. Основной поток использует перегрузку Release(Int32) метода для увеличения числа семафоров до максимального значения, что позволяет трем потокам входить в семафор. Каждый поток использует Thread.Sleep метод для ожидания одной секунды, имитации работы, а затем вызывает 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());
    }
}

Комментарии

Если поток несколько раз вошел в семафор, эта перегрузка метода позволяет восстановить все число семафоров с помощью одного вызова.

Если метод вызывает Release исключениеSemaphoreFullException, оно не обязательно указывает на проблему с вызывающим потоком. Ошибка программирования в другом потоке могла привести к тому, что поток выйдет из семафора больше раз, чем он вошел.

Если текущий Semaphore объект представляет именованный системный семафор, пользователь должен иметь SemaphoreRights.Modify права, а семафор должен быть открыт с SemaphoreRights.Modify правами.

См. также раздел

Применяется к