C# 什么';内核对象和WaitHandle之间的关系是什么?

C# 什么';内核对象和WaitHandle之间的关系是什么?,c#,.net,windows,C#,.net,Windows,下面是一本C#书的引文: WaitHandle类是一个简单的类,其唯一用途是包装Windows内核对象句柄。在内部,WaitHandle基类有一个保存Win32内核的SafeWaitHandle字段 对象句柄。此字段在构造具体的WaitHandle派生类时初始化。对内核对象的每个方法调用都会导致调用线程从托管代码转换为本机用户模式代码,再转换为本机内核模式代码,然后一直返回 我不知道哪个内核对象与WaitHandle关联。以下是MSDN中的一个示例: public class Example {

下面是一本C#书的引文:

WaitHandle类是一个简单的类,其唯一用途是包装Windows内核对象句柄。在内部,WaitHandle基类有一个保存Win32内核的SafeWaitHandle字段 对象句柄。此字段在构造具体的WaitHandle派生类时初始化。对内核对象的每个方法调用都会导致调用线程从托管代码转换为本机用户模式代码,再转换为本机内核模式代码,然后一直返回

我不知道哪个内核对象与WaitHandle关联。以下是MSDN中的一个示例:

public class Example
{
    private static Semaphore _pool;

    private static int _padding;

    public static void Main()
    {       
        _pool = new Semaphore(0, 3);

        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));
            t.Start(i);
        }

        Thread.Sleep(500);

        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(3);

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

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

        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);

        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
公共类示例
{
专用静态信号量池;
私有静态整数填充;
公共静态void Main()
{       
_池=新信号量(0,3);
对于(int i=1;i
工作线程如何使用其他线程的内核对象来阻止自己

工作线程可以访问非自己的句柄的原因是该句柄是一个引用windows内核句柄

Windows内核句柄
windows内核句柄是操作系统范围内的句柄,可以允许

这只是一种花哨的说法,即这个“句柄”是指运行在同一Windows操作系统上的任何线程、进程或程序都可以看到的对象

<> P>一个比较容易的方法是考虑一个共享资源的基本锁。

此锁传统上是这样工作的:使用关键字和
System.Object
的数组可以防止多个线程同时更改其值

让我们看一个简短的例子

类程序
{
私有int[]sharedResource={1};
私有对象myLock=new();
void Worker()
{
锁(myLock)
{
sharedResource[0]=2;
}
}
}
在本例中,我们有一个
工作者
,他锁定
myLock
,并使用数组执行任务

从非常简单的意义上讲,这与WaitHandle做的事情是一样的。唯一的区别是范围和实现细节

范围差异
在我的示例中,
myLock
的范围是任何可以访问
程序的私有成员的内容

因此,默认情况下,任何创建的捕获
(即..
程序
)的工作线程都可以访问
myLock

让我们将其与
WaitHandle
进行比较

等待句柄的作用域是操作系统范围的。这意味着任何可以访问底层内核对象的东西都可以使用它来同步自身

实施差异
在我的示例中,我们只是声明一个对象并使用它,
WaitHandle
通过多个级别在操作系统级别声明句柄(
myLock

对内核对象的每个方法调用都会导致调用线程从托管代码转换为本机用户模式代码,再转换为本机内核模式代码,然后一路返回

我发现最好用一个类比来解释这个问题,因为解释域边界很容易让人们被细节所困扰

考虑我的第一个例子,比如一所房子(
程序
),那里住着一群室友(
工人
线程)

房子的主人(主线)需要做一大堆家务,这样他就可以把要做的家务清单(
myLock
)放在柜台上。任何拥有房子钥匙的人都可以访问该清单,这样他们就可以一起完成它(同步)

相反,使用
WaitHandle
——房子的主人(托管代码),离开房子出去(本机用户模式),坐公交车到市政厅(本机内核模式),并将要完成的工作张贴在公告板上

当众议院议长发布这张便条时,任何去市政厅的人都可以使用这张便条进行同步

当工作线程必须使用
WaitHandle
的方法(如
WaitOne
)时,工作线程就是这样做的。工作线程必须转到操作系统,检查句柄,等待,然后上车回去做一些家务

这就是为什么您的工作线程可以访问主线程句柄,因为该句柄实际上并不属于它,它只是一个便签(参考),告诉工作线程到市政厅去拿便签(锁)

工作线程如何使用其他线程的内核对象来阻止自己

工作线程可以访问非自己的句柄的原因是该句柄是一个引用windows内核句柄

Windows内核句柄
windows内核句柄是操作系统范围内的句柄,可以允许

这只是一种花哨的说法,即这个“句柄”是指运行在同一Windows操作系统上的任何线程、进程或程序都可以看到的对象

<> P>一个比较容易的方法是考虑一个共享资源的基本锁。

此锁传统上是这样工作的:使用关键字和
System.Object
的数组可以防止多个线程同时更改其值

让我们看一个简短的例子

类程序
{
私有int[]sharedResource={1};
私有对象myLock=new();
void Worker()
{
锁(myLock)
{
sharedResource[0]=2;
}
}
}
在本例中,我们有一个
工作者
,他锁定
myLock
,并使用数组执行任务

从非常简单的意义上讲,这与WaitHandle做的事情是一样的。唯一的区别是范围和实现细节

范围差异
myLock的范围