当前位置: 首页 > 面试题库 >

队列上有多重队列

充培
2023-03-14
问题内容

如何queue.Queue同时在多个对象上“选择”

Golang的频道具有所需的功能:

select {
case i1 = <-c1:
    print("received ", i1, " from c1\n")
case c2 <- i2:
    print("sent ", i2, " to c2\n")
case i3, ok := (<-c3):  // same as: i3, ok := <-c3
    if ok {
        print("received ", i3, " from c3\n")
    } else {
        print("c3 is closed\n")
    }
default:
    print("no communication\n")
}

其中第一个要解除阻塞的通道执行相应的块。如何在Python中实现?

更新0

根据tux21b答案中给出的链接,所需的队列类型具有以下属性:

  • 多生产者/多消费者队列(MPMC)
  • 提供每个生产者FIFO / LIFO
  • 当队列为空/完整的消费者/生产者被阻止时

此外,渠道可能会被阻塞,生产者将阻塞,直到消费者取回该物品为止。我不确定Python的Queue是否可以做到这一点。


问题答案:

生产者-
消费者队列有许多不同的实现,例如queue.Queue可用。它们通常具有许多不同的属性,例如DmitryVyukov 在这篇出色的文章中列出的属性。如您所见,可能有超过1万种不同的组合。根据要求,用于这种队列的算法也相差很大。仅扩展现有队列算法以保证其他属性是不可能的,因为这通常需要不同的内部数据结构和不同的算法。

Go的频道提供了相对较高的保证属性,因此这些频道可能适用于许多程序。最困难的要求之一是支持一次读取/阻塞多个通道(select语句),并且如果select语句中可以有多个分支能够继续进行,则要公平地选择一个通道,这样就不会留下任何消息。
。Python的queue.Queue不提供此功能,因此根本无法使用它来存档相同的行为。

因此,如果要继续使用queue.Queue,则需要查找该问题的解决方法。但是,变通办法有其自身的缺点列表,并且较难维护。寻找另一个提供所需功能的生产者-
消费者队列可能是一个更好的主意!无论如何,这是两个可能的解决方法:

轮询

while True:
  try:
    i1 = c1.get_nowait()
    print "received %s from c1" % i1
  except queue.Empty:
    pass
  try:
    i2 = c2.get_nowait()
    print "received %s from c2" % i2
  except queue.Empty:
    pass
  time.sleep(0.1)

在轮询通道时,这可能会占用大量CPU周期,并且在有很多消息时可能会变慢。将time.sleep()与指数退避时间一起使用(而不是此处显示的恒定0.1秒)可能会大大改善此版本。

单个通知队列

queue_id = notify.get()
if queue_id == 1:
  i1 = c1.get()
  print "received %s from c1" % i1
elif queue_id == 2:
  i2 = c2.get()
  print "received %s from c2" % i2

使用此设置,您必须在发送到c1或c2之后将某些内容发送到通知队列。只要您只有一个这样的通知队列就足够了(即您没有多个“选择”,每个“选择”阻塞在通道的不同子集上),这可能对您有用。

另外,您也可以考虑使用Go。无论如何,Go的goroutines和并发支持比Python的有限线程功能强大得多。



 类似资料:
  • 网卡多队列,顾名思义,也就是传统网卡的DMA队列有多个,网卡有基于多个DMA队列的分配机制。多队列网卡已经是当前高速率网卡的主流。 Linux内核中,RPS(Receive Packet Steering)在接收端提供了这样的机制。RPS主要是把软中断的负载均衡到CPU的各个core上,网卡驱动对每个流生成一个hash标识,这个hash值可以通过四元组(源IP地址SIP,源四层端口SPORT,目的

  • 简介 Lumen 的队列服务给不同的后端队列提供统一的 API。队列允许你延迟处理耗时的任务,例如在远程服务器上执行任务,直到您的应用程序可以快速的处理 Web 应用程序的请求。 就像该框架的许多其他部分一样,Lumen 的队列服务跟 Laravel 的队列服务功能相同。因此,如果要了解更多关于 Lumen 的队列,则可以参阅 full Laravel queue documentation. 配

  • 简介 {tip} 现在,Laravel 为你的 Redis 队列提供了 Horizon,一个拥有漂亮的仪表盘的配置系统。 查看完整的 Horizon 文档 Horizon documentation 了解更多信息。 Laravel 队列为不同的队列后台服务提供了统一的 API,比如 Beanstalk, Amazon SQS, Redis, 甚至是关系型数据库。队列可以使你延迟处理一些耗时的任务,

  • 队列是先进先出(FIFO, First-In-First-Out)的线性表,只允许在后端(rear)进行插入操作,在前端(front)进行删除操作。

  • 我将与一起使用中的这个库。所有使用者均为,所有队列均为(4小时)。 我有很多队列没有任何挂起的ack,但仍然保存着数百条消息。此外,队列不会在应该过期时过期,这将在几天后产生性能问题。我没有找到任何理由来解释为什么消息在ack处理之后仍然在队列中。 谢谢 管理工具中的一些快照:

  • 问题内容: 我有一个作业,使用另一个作业的参数触发了该作业。每次给工作分配不同的参数- 运行哪个修订版。 我不想允许同一作业的并发运行,但是我想在该作业的队列中允许多个挂起的构建。 从我尝试过的方法来看,它无效,无论队列中触发了多少个构建,我都只能在队列中看到一个待完成的构建。 任何插件都有可能吗? 问题答案: 如果Jenkins已经包含具有相同param值的构建,则不会将其放置在队列中。 为此,