Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 等待队列与准备队列_.net - Fatal编程技术网

.net 等待队列与准备队列

.net 等待队列与准备队列,.net,.net,为什么在使用监视器时,每个对象都有一个就绪和等待队列?如果一个线程处理了一个对象,只需弹出等待队列中的下一个项目。就绪队列似乎是多余的 上下文是.NET,更具体地说是monitor类。假设我正确理解了您的问题,这两个类的用途不同 “ready”队列用于线程,这些线程可以在获得锁后立即运行。他们只是等着拿到锁。这主要用于互斥,以防止两个线程同时使用同一资源 “等待”队列用于等待特定信号(即监视器脉冲)的线程。这通常用于协调-例如,在生产者/消费者队列中,如果队列为空,消费者将等待监视器脉冲,然后再

为什么在使用监视器时,每个对象都有一个就绪和等待队列?如果一个线程处理了一个对象,只需弹出等待队列中的下一个项目。就绪队列似乎是多余的


上下文是.NET,更具体地说是monitor类。

假设我正确理解了您的问题,这两个类的用途不同

“ready”队列用于线程,这些线程可以在获得锁后立即运行。他们只是等着拿到锁。这主要用于互斥,以防止两个线程同时使用同一资源


“等待”队列用于等待特定信号(即监视器脉冲)的线程。这通常用于协调-例如,在生产者/消费者队列中,如果队列为空,消费者将等待监视器脉冲,然后再次检查队列。虽然没有人在生产,也没有人在消费,但是没有线程拥有监视器——没有资源在使用。但是监视器用于协调消费者与生产者。

生产者/消费者队列是了解监视器类的一个非常好的用例

假设工作偶尔添加到队列中。有时需要处理的项目很多,有时会经过很长一段时间,队列中没有项目

假设有k个消费者线程在等待处理队列中的项目。换句话说,每个线程实现一个紧密循环,不断尝试

  • 请求获取队列上的
    (这将使您进入监视器的“就绪”队列)
  • 获得锁后,检查队列中是否有任何项。如果没有,则有两种释放锁的选择: a) 调用Monitor.Exit,然后调用Monitor.Enter,将自己放在“就绪”队列的后面。 b) 或者,打电话给监视器。等等,然后把自己放在监视器的“等待”队列中
  • 如果您选择选项“a”,您的k线程将浪费CPU周期,在就绪队列中一次又一次地移动,找不到要做的工作,然后在队列的后面重新开始

    如果你选择“b”选项,你的意思是“现在没什么可做的,让我睡觉,有事情要做的时候叫醒我”

    使用选项“b”,如果队列是空的,您很快就会发现您的所有消费者都睡在“等待”队列中,并且不会浪费CPU时间

    然后,当生产者向队列中添加项目时,它调用Monitor.Pulse。这将唤醒“等待”队列中的第一个线程,然后该线程进入“就绪”队列的后面(如果“就绪”队列为空,则该队列也是队列的前面)

    当线程获得锁并从队列中使用此项时,它将调用Monitor.Enter,然后转到“ready”队列的后面


    有关.NET中生产者/消费者队列的经典实现,请参见

    你需要给出上下文。当你回答这个问题时,你在读什么吗?如果是,请链接到它或在此处重复上下文。“in.NET”-什么类?班长还有别的吗?听起来你说的是Windows线程,而不是.NET。请澄清。了解监视器的工作原理很重要。专注于等待和脉冲方法,而不是进入和退出……或者使用巫毒念来找出问题所在。@TimothyShields:嗯,我搜索了“就绪队列”和“等待队列”发现了这个问题:-我怀疑这一个使用了相同的术语。所以你是说pulse会通知消费者什么时候准备好了,所以在此期间消费者线程可以做其他事情。我认为这是不可能的,因为pulse只通知等待队列中的线程,而这些线程已经被阻塞,因此它们不能做任何事情。@user1316459-“因此在此期间,消费者线程可以做其他事情”。不,正好相反。等待队列块中的线程,因此它们不会占用CPU周期,反复获取队列上的锁以查看是否有任何消耗。感谢您提供的详细答案,但您的想法可以通过等待队列(休眠线程队列)轻松实现。为什么对Monitor.Pulse的调用不能将等待队列的第一个元素出列,即为什么它首先必须进入就绪队列?@user1316459-假设随着更多项目添加到任务队列中,所有消费者都很忙(并且所有的Monitor.Pulse调用都没有使用,因为消费者已经醒着并且很忙)。如果只有一个等待队列,那么当每个消费者完成其当前任务时,它将回到等待队列中睡眠,并且不会有任何消费者醒来处理新的工作。@user1316459-“但是您的想法可以很容易地通过等待队列来实现”。我邀请你这样做,并在博客上公开。也许你会有新的想法。也许你不会,但一路上你会对所有问题有深入的了解。”如果只有一个等待队列,那么当每个消费者完成其当前任务时,它会回到等待队列中睡觉“不,不会。在每个使用者完成其工作后,它将尝试获取锁。这里只能发生两件事:1。它需要锁,接受任务并释放锁。没问题。2.它不需要锁,因为另一个使用者当前正在执行任务。因此,它进入了睡眠(等待)队列。另一个消费者现在已经完成了自己的任务,并对睡眠(等待)队列进行了脉冲处理。因此,最初的消费者现在可以再试一次。@user1316459-我不知道你的方法是如何工作的,答案的评论部分实际上不是进行长时间讨论的地方。但是去尝试一下,如果你有什么想法,让每个人都知道。