Semaphore 构造函数

定义

初始化 Semaphore 类的新实例。

重载

名称 说明
Semaphore(Int32, Int32)

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数。

Semaphore(Int32, Int32, String)

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,并选择性地指定系统信号灯对象的名称。

Semaphore(Int32, Int32, String, Boolean)

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称,并指定一个变量,该值接收指示是否创建了新的系统信号灯的值。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

初始化类的新实例 Semaphore ,指定初始条目数和并发条目的最大数目,并选择性地指定系统信号灯对象的名称和用于设置用户范围和会话范围访问的选项。

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

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称,指定一个变量,该值指示是否创建了新的系统信号灯,并指定系统信号灯的安全访问控制。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称和用于设置用户范围和会话范围访问的选项,并指定一个变量,用于接收指示是否创建了新的系统信号灯的值。

Semaphore(Int32, Int32)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数。

public:
 Semaphore(int initialCount, int maximumCount);
public Semaphore(int initialCount, int maximumCount);
new System.Threading.Semaphore : int * int -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer)

参数

initialCount
Int32

可以同时授予信号灯的初始请求数。

maximumCount
Int32

可以同时授予信号灯的最大请求数。

例外

initialCount 大于 maximumCount

maximumCount 小于 1。

-或-

initialCount 小于 0。

示例

以下示例创建一个信号灯,最大计数为 3,初始计数为零。 该示例启动五个线程,该线程阻止等待信号灯。 主线程使用 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());
    }
}
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

注解

此构造函数初始化未命名信号灯。 使用此类信号灯实例的所有线程都必须具有对该实例的引用。

如果 initialCount 小于 maximumCount,效果与当前线程已调用 WaitOnemaximumCountinitialCount) 次相同。 如果不想为创建信号灯的线程保留任何条目,请使用相同的数字和 maximumCountinitialCount

另请参阅

适用于

Semaphore(Int32, Int32, String)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,并选择性地指定系统信号灯对象的名称。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name);
public Semaphore(int initialCount, int maximumCount, string name);
public Semaphore(int initialCount, int maximumCount, string? name);
new System.Threading.Semaphore : int * int * string -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String)

参数

initialCount
Int32

可以同时授予信号灯的初始请求数。

maximumCount
Int32

可以同时授予信号灯的最大请求数。

name
String

如果同步对象要与其他进程共享,则为名称;否则为 null 空字符串。 名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅“备注”部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

例外

initialCount 大于 maximumCount

-或-

仅.NET框架:name的长度超过MAX_PATH(260 个字符)。

maximumCount 小于 1。

-或-

initialCount 小于 0。

name 无效。 这可能是出于各种原因,包括操作系统可能放置的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

-或-

还有其他一些错误。 该 HResult 属性可能提供更多信息。

仅Windows:name指定了未知命名空间。 有关详细信息,请参阅 对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名信号灯存在并且具有访问控制安全性,并且用户没有 FullControl

无法创建具有提供的 name 同步对象。 不同类型的同步对象可能具有相同的名称。

示例

下面的代码示例演示命名信号灯的跨进程行为。 该示例创建一个命名信号灯,最大计数为 5,初始计数为 5。 程序对该方法进行三次调用 WaitOne 。 因此,如果从两个命令窗口运行编译的示例,第二个副本将在第三次调用 WaitOne时阻止。 释放程序第一个副本中的一个或多个条目以取消阻止第二个条目。

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample3". The semaphore has a
        // maximum count of five. The initial count is also five. 
        // There is no point in using a smaller initial count,
        // because the initial count is not used if this program
        // doesn't create the named system semaphore, and with 
        // this method overload there is no way to tell. Thus, this
        // program assumes that it is competing with other
        // programs for the semaphore.
        //
        Semaphore sem = new Semaphore(5, 5, "SemaphoreExample3");

        // Attempt to enter the semaphore three times. If another 
        // copy of this program is already running, only the first
        // two requests can be satisfied. The third blocks. Note 
        // that in a real application, timeouts should be used
        // on the WaitOne calls, to avoid deadlocks.
        //
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore once.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore twice.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore three times.");

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    }
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample3". The semaphore has a
        ' maximum count of five. The initial count is also five. 
        ' There is no point in using a smaller initial count,
        ' because the initial count is not used if this program
        ' doesn't create the named system semaphore, and with 
        ' this method overload there is no way to tell. Thus, this
        ' program assumes that it is competing with other
        ' programs for the semaphore.
        '
        Dim sem As New Semaphore(5, 5, "SemaphoreExample3")

        ' Attempt to enter the semaphore three times. If another 
        ' copy of this program is already running, only the first
        ' two requests can be satisfied. The third blocks. Note 
        ' that in a real application, timeouts should be used
        ' on the WaitOne calls, to avoid deadlocks.
        '
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore once.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore twice.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore three times.")

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

注解

此构造函数初始化表示 Semaphore 命名系统信号灯的对象。 可以创建表示同一命名系统信号灯的多个 Semaphore 对象。

name可以是前缀Global\,也可以Local\指定命名空间。 Global指定命名空间后,同步对象可以与系统上的任何进程共享。 Local指定命名空间时,这也是未指定命名空间时的默认命名空间,同步对象可以与同一会话中的进程共享。 在Windows,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似 Unix 的操作系统上,每个 shell 都有自己的会话。 会话本地同步对象可能适合在进程与父/子关系之间同步,其中它们都在同一会话中运行。 有关Windows上的同步对象名称的详细信息,请参阅 Object Names

如果提供了一个 name 且请求类型的同步对象已存在于命名空间中,则使用现有同步对象。 如果命名空间中已存在不同类型的同步对象,则会引发一个 WaitHandleCannotBeOpenedException 。 否则,将创建新的同步对象。

如果命名的系统信号灯不存在,则会使用指定的初始计数和最大计数initialCountmaximumCount创建它。 如果命名的系统信号灯已存在且 initialCountmaximumCount 未使用,但无效值仍会导致异常。 如果需要确定是否创建了命名系统信号灯,请改用 Semaphore(Int32, Int32, String, Boolean) 构造函数重载。

重要

使用此构造函数重载时,建议的做法是为和maximumCount指定相同的数字initialCount。 如果 initialCount 小于 maximumCount,并且创建了一个命名的系统信号灯,则效果与当前线程已调用 WaitOnemaximumCountinitialCount)时间相同。 但是,使用此构造函数重载,无法确定是否已创建命名系统信号灯。

如果指定 null 或为 name空字符串,则会创建本地信号灯,就像调用 Semaphore(Int32, Int32) 构造函数重载一样。

由于命名信号灯在整个操作系统中可见,因此可用于协调跨进程边界的资源使用。

如果想要确定命名的系统信号灯是否存在,请使用该方法 OpenExisting 。 该方法 OpenExisting 尝试打开现有的命名信号量,如果系统信号灯不存在,则会引发异常。

注意

默认情况下,命名信号灯不限于创建信号灯的用户。 其他用户可能能够打开和使用信号灯,包括通过多次获取信号灯而不释放信号灯来干扰信号灯。 若要限制对特定用户的访问,可以使用构造函数重载或在 SemaphoreAcl 创建命名信号量时传入 SemaphoreSecurity 。 避免在可能具有不受信任的用户运行代码的系统上使用命名信号灯,而不受访问限制。

另请参阅

适用于

Semaphore(Int32, Int32, String, Boolean)

Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs
Source:
Semaphore.cs

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称,并指定一个变量,该值接收指示是否创建了新的系统信号灯的值。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew);
public Semaphore(int initialCount, int maximumCount, string? name, out bool createdNew);
new System.Threading.Semaphore : int * int * string * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean)

参数

initialCount
Int32

可以同时满足的信号灯的初始请求数。

maximumCount
Int32

可以并发满足的信号灯的最大请求数。

name
String

如果同步对象要与其他进程共享,则为名称;否则为 null 空字符串。 名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅“备注”部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

createdNew
Boolean

此方法返回时,包含 true 是否创建了本地信号灯(即,如果 namenull 空字符串),或者创建指定的命名系统信号灯; false 如果指定的命名系统信号灯已存在。 此参数未初始化传递。

例外

initialCount 大于 maximumCount

-或-

仅.NET框架:name的长度超过MAX_PATH(260 个字符)。

maximumCount 小于 1。

-或-

initialCount 小于 0。

name 无效。 这可能是出于各种原因,包括操作系统可能放置的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

-或-

还有其他一些错误。 该 HResult 属性可能提供更多信息。

仅Windows:name指定了未知命名空间。 有关详细信息,请参阅 对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名信号灯存在并且具有访问控制安全性,并且用户没有 FullControl

无法创建具有提供的 name 同步对象。 不同类型的同步对象可能具有相同的名称。

示例

下面的代码示例演示命名信号灯的跨进程行为。 该示例创建一个命名信号灯,最大计数为 5,初始计数为 2。 也就是说,它为调用构造函数的线程保留三个条目。 false如果是createNew,程序对该方法进行三次调用WaitOne。 因此,如果从两个命令窗口运行编译的示例,第二个副本将在第三次调用 WaitOne时阻止。 释放程序第一个副本中的一个或多个条目以取消阻止第二个条目。

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // The value of this variable is set by the semaphore
        // constructor. It is true if the named system semaphore was
        // created, and false if the named semaphore already existed.
        //
        bool semaphoreWasCreated;

        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample". The semaphore has a
        // maximum count of five, and an initial count of two. The
        // Boolean value that indicates creation of the underlying 
        // system object is placed in semaphoreWasCreated.
        //
        Semaphore sem = new Semaphore(2, 5, "SemaphoreExample", 
            out semaphoreWasCreated);

        if (semaphoreWasCreated)
        {
            // If the named system semaphore was created, its count is
            // set to the initial count requested in the constructor.
            // In effect, the current thread has entered the semaphore
            // three times.
            // 
            Console.WriteLine("Entered the semaphore three times.");
        }
        else
        {      
            // If the named system semaphore was not created,  
            // attempt to enter it three times. If another copy of
            // this program is already running, only the first two
            // requests can be satisfied. The third blocks.
            //
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore once.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore twice.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore three times.");
        }

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    } 
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' The value of this variable is set by the semaphore
        ' constructor. It is True if the named system semaphore was
        ' created, and False if the named semaphore already existed.
        '
        Dim semaphoreWasCreated As Boolean

        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample". The semaphore has a
        ' maximum count of five, and an initial count of two. The
        ' Boolean value that indicates creation of the underlying 
        ' system object is placed in semaphoreWasCreated.
        '
        Dim sem As New Semaphore(2, 5, "SemaphoreExample", _
            semaphoreWasCreated)

        If semaphoreWasCreated Then
            ' If the named system semaphore was created, its count is
            ' set to the initial count requested in the constructor.
            ' In effect, the current thread has entered the semaphore
            ' three times.
            ' 
            Console.WriteLine("Entered the semaphore three times.")
        Else
            ' If the named system semaphore was not created,  
            ' attempt to enter it three times. If another copy of
            ' this program is already running, only the first two
            ' requests can be satisfied. The third blocks.
            '
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore once.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore twice.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore three times.")
        End If

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

注解

name可以是前缀Global\,也可以Local\指定命名空间。 Global指定命名空间后,同步对象可以与系统上的任何进程共享。 Local指定命名空间时,这也是未指定命名空间时的默认命名空间,同步对象可以与同一会话中的进程共享。 在Windows,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似 Unix 的操作系统上,每个 shell 都有自己的会话。 会话本地同步对象可能适合在进程与父/子关系之间同步,其中它们都在同一会话中运行。 有关Windows上的同步对象名称的详细信息,请参阅 Object Names

如果提供了一个 name 且请求类型的同步对象已存在于命名空间中,则使用现有同步对象。 如果命名空间中已存在不同类型的同步对象,则会引发一个 WaitHandleCannotBeOpenedException 。 否则,将创建新的同步对象。

此构造函数初始化表示 Semaphore 命名系统信号灯的对象。 可以创建表示同一命名系统信号灯的多个 Semaphore 对象。

如果命名的系统信号灯不存在,则会使用指定的初始计数和最大计数initialCountmaximumCount创建它。 如果命名的系统信号灯已存在且 initialCountmaximumCount 未使用,但无效值仍会导致异常。 用于 createdNew 确定是否创建了系统信号灯。

如果 initialCount 小于 maximumCount,并且 createdNewtrue,效果与当前线程已调用 WaitOnemaximumCountinitialCount) 次相同。

如果指定 null 或为 name空字符串,则会创建本地信号灯,就像调用 Semaphore(Int32, Int32) 构造函数重载一样。 在这种情况下, createdNew 始终 true为 .

由于命名信号灯在整个操作系统中可见,因此可用于协调跨进程边界的资源使用。

注意

默认情况下,命名信号灯不限于创建信号灯的用户。 其他用户可能能够打开和使用信号灯,包括通过多次获取信号灯而不释放信号灯来干扰信号灯。 若要限制对特定用户的访问,可以使用构造函数重载或在 SemaphoreAcl 创建命名信号量时传入 SemaphoreSecurity 。 避免在可能具有不受信任的用户运行代码的系统上使用命名信号灯,而不受访问限制。

另请参阅

适用于

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

Source:
Semaphore.cs
Source:
Semaphore.cs

初始化类的新实例 Semaphore ,指定初始条目数和并发条目的最大数目,并选择性地指定系统信号灯对象的名称和用于设置用户范围和会话范围访问的选项。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, System::Threading::NamedWaitHandleOptions options);
public Semaphore(int initialCount, int maximumCount, string? name, System.Threading.NamedWaitHandleOptions options);
new System.Threading.Semaphore : int * int * string * System.Threading.NamedWaitHandleOptions -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, options As NamedWaitHandleOptions)

参数

initialCount
Int32

可以同时满足的信号灯的初始请求数。

maximumCount
Int32

可以并发满足的信号灯的最大请求数。

name
String

如果同步对象要与其他进程共享,则为名称;否则为 null 空字符串。 名称区分大小写。

options
NamedWaitHandleOptions

命名信号灯的范围选项。 默认只能访问当前用户和当前会话。 指定的选项可能会影响名称和对基础信号灯对象的访问的命名空间。

例外

initialCount 大于 maximumCount

-或-

initialCount 小于 0。

name 无效。 这可能是出于各种原因,包括操作系统可能放置的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

-或-

还有其他一些错误。 该 HResult 属性可能提供更多信息。

仅Windows:name指定了未知命名空间。 有关详细信息,请参阅 对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名信号灯存在并且具有访问控制安全性,并且用户没有 FullControl

无法创建具有提供的 name 同步对象。 不同类型的同步对象可能具有相同的名称。

-或-

具有指定 name 对象的存在,但指定的 options 对象与现有对象的选项不兼容。

注解

此构造函数初始化表示 Semaphore 命名系统信号灯的对象。 可以创建表示同一命名系统信号灯的多个 Semaphore 对象。

如果命名空间中已存在请求类型的同步name对象和同步对象,则使用现有同步对象,除非options指定对当前用户的访问权限,并且同步对象与它不兼容,在这种情况下会引发。WaitHandleCannotBeOpenedException 如果命名空间中已存在不同类型的同步对象,也会引发一个 WaitHandleCannotBeOpenedException 同步对象。 否则,将创建新的同步对象。

如果命名的系统信号灯不存在,则会使用指定的初始计数和最大计数initialCountmaximumCount创建它。 如果命名的系统信号灯已存在且 initialCountmaximumCount 未使用,但无效值仍会导致异常。 如果需要确定是否创建了命名系统信号灯,请改用 Semaphore(Int32, Int32, String, Boolean) 构造函数重载。

重要

使用此构造函数重载时,建议的做法是为和maximumCount指定相同的数字initialCount。 如果 initialCount 小于 maximumCount,并且创建了一个命名的系统信号灯,则效果与当前线程已调用 WaitOnemaximumCountinitialCount)时间相同。 但是,使用此构造函数重载,无法确定是否已创建命名的系统信号灯。

如果指定 null 或为 name空字符串,则会创建本地信号灯,就像调用 Semaphore(Int32, Int32) 构造函数重载一样。

由于命名信号灯在整个操作系统中可见,因此可用于协调跨进程边界的资源使用。

如果想要确定命名的系统信号灯是否存在,请使用该方法 OpenExisting 。 该方法 OpenExisting 尝试打开现有的命名信号量,如果系统信号灯不存在,则会引发异常。

在Windows,可以提供 options,以指定是否可以仅对当前用户或所有用户访问命名信号量。 它还允许你指定是否可以仅对当前会话中的进程或所有会话访问命名信号量。 有关详细信息,请参阅 NamedWaitHandleOptions

注意

在基于 Unix 的操作系统上, options 不支持参数,因为不支持命名信号灯。

另请参阅

适用于

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

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称,指定一个变量,该值指示是否创建了新的系统信号灯,并指定系统信号灯的安全访问控制。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::SemaphoreSecurity ^ semaphoreSecurity);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity);
new System.Threading.Semaphore : int * int * string * bool * System.Security.AccessControl.SemaphoreSecurity -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean, semaphoreSecurity As SemaphoreSecurity)

参数

initialCount
Int32

可以同时满足的信号灯的初始请求数。

maximumCount
Int32

可以并发满足的信号灯的最大请求数。

name
String

如果同步对象要与其他进程共享,则为名称;否则为 null 空字符串。 名称区分大小写。 反斜杠字符 (\) 是保留的,只能用于指定命名空间。 有关命名空间的详细信息,请参阅“备注”部分。 根据操作系统,名称可能会有进一步的限制。 例如,在基于 Unix 的操作系统上,排除命名空间后的名称必须是有效的文件名。

createdNew
Boolean

此方法返回时,包含 true 是否创建了本地信号灯(即,如果 namenull 空字符串),或者创建指定的命名系统信号灯; false 如果指定的命名系统信号灯已存在。 此参数未初始化传递。

semaphoreSecurity
SemaphoreSecurity

一个 SemaphoreSecurity 对象,表示要应用于命名系统信号灯的访问控制安全性。

例外

initialCount 大于 maximumCount

-或-

仅.NET框架:name的长度超过MAX_PATH(260 个字符)。

maximumCount 小于 1。

-或-

initialCount 小于 0。

命名信号灯存在并且具有访问控制安全性,并且用户没有 FullControl

name 无效。 这可能是出于各种原因,包括操作系统可能放置的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

-或-

还有其他一些错误。 该 HResult 属性可能提供更多信息。

仅Windows:name指定了未知命名空间。 有关详细信息,请参阅 对象名称

name 太长。 长度限制可能取决于操作系统或配置。

无法创建具有提供的 name 同步对象。 不同类型的同步对象可能具有相同的名称。

示例

下面的代码示例演示具有访问控制安全性的命名信号灯的跨进程行为。 该示例使用 OpenExisting(String) 方法重载测试命名信号灯是否存在。 如果信号灯不存在,则创建信号灯的最大计数为 2,访问控制安全性可拒绝当前用户使用信号灯的权限,但授予对信号灯的读取和更改权限的权限。 如果从两个命令窗口运行编译的示例,则第二个副本将在调用 OpenExisting(String) 该方法时引发访问冲突异常。 捕获异常,该示例使用 OpenExisting(String, SemaphoreRights) 方法重载打开信号灯,并具有读取和更改权限所需的权限。

更改权限后,信号灯将打开,并具有输入和释放所需的权限。 如果从第三个命令窗口运行已编译的示例,则它使用新权限运行。

using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string semaphoreName = "SemaphoreExample5";

        Semaphore sem = null;
        bool doesNotExist = false;
        bool unauthorized = false;

        // Attempt to open the named semaphore.
        try
        {
            // Open the semaphore with (SemaphoreRights.Synchronize
            // | SemaphoreRights.Modify), to enter and release the
            // named semaphore.
            //
            sem = Semaphore.OpenExisting(semaphoreName);
        }
        catch(WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Semaphore does not exist.");
            doesNotExist = true;
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
            unauthorized = true;
        }

        // There are three cases: (1) The semaphore does not exist.
        // (2) The semaphore exists, but the current user doesn't 
        // have access. (3) The semaphore exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The semaphore does not exist, so create it.
            //
            // The value of this variable is set by the semaphore
            // constructor. It is true if the named system semaphore was
            // created, and false if the named semaphore already existed.
            //
            bool semaphoreWasCreated;

            // Create an access control list (ACL) that denies the
            // current user the right to enter or release the 
            // semaphore, but allows the right to read and change
            // security information for the semaphore.
            //
            string user = Environment.UserDomainName + "\\" 
                + Environment.UserName;
            SemaphoreSecurity semSec = new SemaphoreSecurity();

            SemaphoreAccessRule rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                AccessControlType.Deny);
            semSec.AddAccessRule(rule);

            rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.ReadPermissions | SemaphoreRights.ChangePermissions,
                AccessControlType.Allow);
            semSec.AddAccessRule(rule);

            // Create a Semaphore object that represents the system
            // semaphore named by the constant 'semaphoreName', with
            // maximum count three, initial count three, and the
            // specified security access. The Boolean value that 
            // indicates creation of the underlying system object is
            // placed in semaphoreWasCreated.
            //
            sem = new Semaphore(3, 3, semaphoreName, 
                out semaphoreWasCreated, semSec);

            // If the named system semaphore was created, it can be
            // used by the current instance of this program, even 
            // though the current user is denied access. The current
            // program enters the semaphore. Otherwise, exit the
            // program.
            // 
            if (semaphoreWasCreated)
            {
                Console.WriteLine("Created the semaphore.");
            }
            else
            {
                Console.WriteLine("Unable to create the semaphore.");
                return;
            }
        }
        else if (unauthorized)
        {
            // Open the semaphore to read and change the access
            // control security. The access control security defined
            // above allows the current user to do this.
            //
            try
            {
                sem = Semaphore.OpenExisting(
                    semaphoreName, 
                    SemaphoreRights.ReadPermissions 
                        | SemaphoreRights.ChangePermissions);

                // Get the current ACL. This requires 
                // SemaphoreRights.ReadPermissions.
                SemaphoreSecurity semSec = sem.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\" 
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the semaphore must
                // be removed.
                SemaphoreAccessRule rule = new SemaphoreAccessRule(
                    user, 
                    SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                    AccessControlType.Deny);
                semSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new SemaphoreAccessRule(user, 
                     SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                     AccessControlType.Allow);
                semSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec);

                Console.WriteLine("Updated semaphore security.");

                // Open the semaphore with (SemaphoreRights.Synchronize 
                // | SemaphoreRights.Modify), the rights required to
                // enter and release the semaphore.
                //
                sem = Semaphore.OpenExisting(semaphoreName);
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}", ex.Message);
                return;
            }
        }

        // Enter the semaphore, and hold it until the program
        // exits.
        //
        try
        {
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore.");
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            sem.Release();
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
        }
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const semaphoreName As String = "SemaphoreExample5"

        Dim sem As Semaphore = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' Attempt to open the named semaphore.
        Try
            ' Open the semaphore with (SemaphoreRights.Synchronize
            ' Or SemaphoreRights.Modify), to enter and release the
            ' named semaphore.
            '
            sem = Semaphore.OpenExisting(semaphoreName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Semaphore does not exist.")
            doesNotExist = True
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", ex.Message)
            unauthorized = True
        End Try

        ' There are three cases: (1) The semaphore does not exist.
        ' (2) The semaphore exists, but the current user doesn't 
        ' have access. (3) The semaphore exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The semaphore does not exist, so create it.
            '
            ' The value of this variable is set by the semaphore
            ' constructor. It is True if the named system semaphore was
            ' created, and False if the named semaphore already existed.
            '
            Dim semaphoreWasCreated As Boolean

            ' Create an access control list (ACL) that denies the
            ' current user the right to enter or release the 
            ' semaphore, but allows the right to read and change
            ' security information for the semaphore.
            '
            Dim user As String = Environment.UserDomainName _ 
                & "\" & Environment.UserName
            Dim semSec As New SemaphoreSecurity()

            Dim rule As New SemaphoreAccessRule(user, _
                SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                AccessControlType.Deny)
            semSec.AddAccessRule(rule)

            rule = New SemaphoreAccessRule(user, _
                SemaphoreRights.ReadPermissions Or _
                SemaphoreRights.ChangePermissions, _
                AccessControlType.Allow)
            semSec.AddAccessRule(rule)

            ' Create a Semaphore object that represents the system
            ' semaphore named by the constant 'semaphoreName', with
            ' maximum count three, initial count three, and the
            ' specified security access. The Boolean value that 
            ' indicates creation of the underlying system object is
            ' placed in semaphoreWasCreated.
            '
            sem = New Semaphore(3, 3, semaphoreName, _
                semaphoreWasCreated, semSec)

            ' If the named system semaphore was created, it can be
            ' used by the current instance of this program, even 
            ' though the current user is denied access. The current
            ' program enters the semaphore. Otherwise, exit the
            ' program.
            ' 
            If semaphoreWasCreated Then
                Console.WriteLine("Created the semaphore.")
            Else
                Console.WriteLine("Unable to create the semaphore.")
                Return
            End If

        ElseIf unauthorized Then

            ' Open the semaphore to read and change the access
            ' control security. The access control security defined
            ' above allows the current user to do this.
            '
            Try
                sem = Semaphore.OpenExisting(semaphoreName, _
                    SemaphoreRights.ReadPermissions Or _
                    SemaphoreRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' SemaphoreRights.ReadPermissions.
                Dim semSec As SemaphoreSecurity = sem.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the semaphore must
                ' be removed.
                Dim rule As New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Deny)
                semSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Allow)
                semSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec)

                Console.WriteLine("Updated semaphore security.")

                ' Open the semaphore with (SemaphoreRights.Synchronize 
                ' Or SemaphoreRights.Modify), the rights required to
                ' enter and release the semaphore.
                '
                sem = Semaphore.OpenExisting(semaphoreName)

            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unable to change permissions: {0}", _
                    ex.Message)
                Return
            End Try

        End If

        ' Enter the semaphore, and hold it until the program
        ' exits.
        '
        Try
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore.")
            Console.WriteLine("Press the Enter key to exit.")
            Console.ReadLine()
            sem.Release()
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", _
                ex.Message)
        End Try
    End Sub 
End Class

注解

使用此构造函数在创建命名系统信号灯时将访问控制安全性应用于命名系统信号量,从而阻止其他代码控制信号灯。

name可以是前缀Global\,也可以Local\指定命名空间。 Global指定命名空间后,同步对象可以与系统上的任何进程共享。 Local指定命名空间时,这也是未指定命名空间时的默认命名空间,同步对象可以与同一会话中的进程共享。 在Windows,会话是登录会话,服务通常在不同的非交互式会话中运行。 在类似 Unix 的操作系统上,每个 shell 都有自己的会话。 会话本地同步对象可能适合在进程与父/子关系之间同步,其中它们都在同一会话中运行。 有关Windows上的同步对象名称的详细信息,请参阅 Object Names

如果提供了一个 name 且请求类型的同步对象已存在于命名空间中,则使用现有同步对象。 如果命名空间中已存在不同类型的同步对象,则会引发一个 WaitHandleCannotBeOpenedException 。 否则,将创建新的同步对象。

此构造函数初始化表示 Semaphore 命名系统信号灯的对象。 可以创建表示同一命名系统信号灯的多个 Semaphore 对象。

如果命名系统信号灯不存在,则会使用指定的访问控制安全性创建它。 如果命名信号灯存在,则忽略指定的访问控制安全性。

Note

调用方可以完全控制新创建 Semaphore 的对象,即使 semaphoreSecurity 拒绝或未能向当前用户授予某些访问权限。 但是,如果当前用户尝试获取另一个 Semaphore 对象来表示同一个命名信号灯,则使用构造函数或 OpenExisting 方法应用访问控制安全性Windows。

如果命名的系统信号灯不存在,则会使用指定的初始计数和最大计数initialCountmaximumCount创建它。 如果命名的系统信号灯已存在且 initialCountmaximumCount 未使用,但无效值仍会导致异常。 使用 createdNew 参数确定系统信号灯是否由此构造函数创建。

如果 initialCount 小于 maximumCount,并且 createdNewtrue,效果与当前线程已调用 WaitOnemaximumCountinitialCount) 次相同。

如果指定 null 或为 name空字符串,则会创建本地信号灯,就像调用 Semaphore(Int32, Int32) 构造函数重载一样。 在这种情况下, createdNew 始终 true为 .

由于命名信号灯在整个操作系统中可见,因此可用于协调跨进程边界的资源使用。

注意

默认情况下,命名信号灯不限于创建信号灯的用户。 其他用户可能能够打开和使用信号灯,包括通过多次获取信号灯而不释放信号灯来干扰信号灯。 若要限制对特定用户的访问,可以在创建命名信号灯时传入 SemaphoreSecurity 。 避免在可能具有不受信任的用户运行代码的系统上使用命名信号灯,而不受访问限制。

另请参阅

适用于

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

Source:
Semaphore.cs
Source:
Semaphore.cs

初始化类的新实例 Semaphore ,指定初始条目数和最大并发条目数,(可选)指定系统信号灯对象的名称和用于设置用户范围和会话范围访问的选项,并指定一个变量,用于接收指示是否创建了新的系统信号灯的值。

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, System::Threading::NamedWaitHandleOptions options, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore(int initialCount, int maximumCount, string? name, System.Threading.NamedWaitHandleOptions options, out bool createdNew);
new System.Threading.Semaphore : int * int * string * System.Threading.NamedWaitHandleOptions * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, options As NamedWaitHandleOptions, ByRef createdNew As Boolean)

参数

initialCount
Int32

可以同时满足的信号灯的初始请求数。

maximumCount
Int32

可以并发满足的信号灯的最大请求数。

name
String

如果同步对象要与其他进程共享,则为名称;否则为 null 空字符串。 名称区分大小写。

options
NamedWaitHandleOptions

命名信号灯的范围选项。 默认只能访问当前用户和当前会话。 指定的选项可能会影响名称和对基础信号灯对象的访问的命名空间。

createdNew
Boolean

此方法返回时,包含 true 是否创建了本地信号灯(即,如果 namenull 空字符串),或者是否创建了指定的命名系统信号量;包含 false 指定的命名系统信号量是否已存在。 此参数未初始化传递。

例外

initialCount 大于 maximumCount

-或-

initialCount 小于 0。

name 无效。 这可能是出于各种原因,包括操作系统可能放置的一些限制,例如未知前缀或无效字符。 请注意,名称和通用前缀“Global\”和“Local\”区分大小写。

-或-

还有其他一些错误。 该 HResult 属性可能提供更多信息。

仅Windows:name指定了未知命名空间。 有关详细信息,请参阅 对象名称

name 太长。 长度限制可能取决于操作系统或配置。

命名信号灯存在并且具有访问控制安全性,并且用户没有 FullControl

无法创建具有提供的 name 同步对象。 不同类型的同步对象可能具有相同的名称。

-或-

具有指定 name 对象的存在,但指定的 options 对象与现有对象的选项不兼容。

注解

如果命名空间中已存在请求类型的同步name对象和同步对象,则使用现有同步对象,除非options指定对当前用户的访问权限,并且同步对象与它不兼容,在这种情况下会引发。WaitHandleCannotBeOpenedException 如果命名空间中已存在不同类型的同步对象,也会引发一个 WaitHandleCannotBeOpenedException 同步对象。 否则,将创建新的同步对象。

此构造函数初始化表示 Semaphore 命名系统信号灯的对象。 可以创建表示同一命名系统信号灯的多个 Semaphore 对象。

如果命名的系统信号灯不存在,则会使用指定的初始计数和最大计数initialCountmaximumCount创建它。 如果命名的系统信号灯已存在且 initialCountmaximumCount 未使用,但无效值仍会导致异常。 使用 createdNew 参数确定系统信号灯是否由此构造函数创建。

如果 initialCount 小于 maximumCount,并且 createdNewtrue,效果与当前线程已调用 WaitOnemaximumCountinitialCount) 次相同。

如果指定 null 或为 name空字符串,则会创建本地信号灯,就像调用 Semaphore(Int32, Int32) 构造函数重载一样。 在这种情况下, createdNew 始终 true为 .

由于命名信号灯在整个操作系统中可见,因此可用于协调跨进程边界的资源使用。

在Windows,可以提供 options,以指定是否可以仅对当前用户或所有用户访问命名信号量。 它还允许你指定是否可以仅对当前会话中的进程或所有会话访问命名信号量。 有关详细信息,请参阅 NamedWaitHandleOptions

注意

在基于 Unix 的操作系统上, options 不支持参数,因为不支持命名信号灯。

另请参阅

适用于