- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
有谁知道从 multiprocessing.Queue
获得接近 LIFO 甚至不接近 FIFO(例如随机)行为的干净方法?
替代问题:有人可以指出管理 multiprocessing.Queue
背后的实际存储结构的线程的代码吗? 这似乎是微不足道的提供大约后进先出的访问权限,但我在试图找到它的过程中迷失了方向。
注意事项:
multiprocessing.Queue
does not guarantee order .美好的。但它是 near-FIFO,所以 near-LIFO 会很棒。(编辑)澄清一下:我正在使用 multiprocessing
进行 CPU 限制模拟,因此不能使用 Queue
中的专用队列。由于我已经几天没有看到任何答案,所以我在上面添加了备选问题。
如果这是一个问题,下面是 multiprocessing.Queue
接近 FIFO 的轻微证据。它只是表明在一个简单的情况下(单线程),它在我的系统上完全是 FIFO:
import multiprocessing as mp
import Queue
q = mp.Queue()
for i in xrange(1000):
q.put(i)
deltas = []
while True:
try:
value1 = q.get(timeout=0.1)
value2 = q.get(timeout=0.1)
deltas.append(value2-value1)
except Queue.Empty:
break
#positive deltas would indicate the numbers are coming out in increasing order
min_delta, max_delta = min(deltas), max(deltas)
avg_delta = sum(deltas)/len(deltas)
print "min", min_delta
print "max", max_delta
print "avg", avg_delta
打印:最小值、最大值和平均值恰好为 1(完美的 FIFO)
最佳答案
我查看了我的 Python 安装(Python 2.7,但与我简要介绍的 Python 3.2 版本没有明显不同的 Lib/multiprocessing/queues.py
中的 Queue 类检查)。以下是我的理解:
队列对象维护着两组对象。一组是所有进程共享的多进程安全原语。其他的由每个进程单独创建和使用。
跨进程对象在__init__
方法中设置:
Pipe
对象,其两端分别保存为self._reader
和self._writer
。BoundedSemaphore
对象,它计算(并可选地限制)队列中的对象数量。Lock
对象用于读取管道,在非 Windows 平台上另一个用于写入。 (我假设这是因为写入管道在 Windows 上本质上是多进程安全的。)每个进程对象在 _after_fork
和 _start_thread
方法中设置:
collections.deque
对象,用于缓冲写入 Pipe。threading.condition
对象,用于在缓冲区不为空时发出信号。threading.Thread
对象。它是延迟创建的,因此在给定进程中至少请求对队列进行一次写入之前,它不会存在。Finalize
对象,在进程结束时清除内容。从队列中get
非常简单。您获取读锁,递减信号量,并从 Pipe 的读端获取一个对象。
put
更复杂。它使用多个线程。 put
的调用者获取条件的锁,然后将其对象添加到缓冲区并在解锁之前向条件发出信号。它还会增加信号量并启动编写器线程(如果它尚未运行)。
编写器线程在 _feed
方法中永远循环(直到被取消)。如果缓冲区为空,它会等待 notempty
条件。然后它从缓冲区中取出一个项目,获取写锁(如果它存在)并将该项目写入管道。
那么,鉴于所有这些,您能否修改它以获得后进先出队列?这似乎并不容易。管道本质上是 FIFO 对象,虽然 Queue 不能保证整体的 FIFO 行为(由于来自多个进程的写入的异步性质)它总是主要是 FIFO。
如果您只有一个消费者,您可以从队列中获取
对象并将它们添加到您自己的进程本地堆栈中。做一个多消费者堆栈会更难,尽管使用共享内存一个有界大小的堆栈不会太难。您需要一把锁、一对条件(用于在满状态和空状态时阻塞/发出信号)、一个共享整数值(用于保存值的数量)和一个适当类型的共享数组(用于值本身)。
关于python - 从 multiprocessing.Queue 获得近后进先出行为的干净方法? (甚至只是*不*接近先进先出),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12042575/
我刚刚开始使用 javascript,多年来一直使用 C# 和 OO 语言。 我发现我将我的代码放在这样的文件中, database.js sync.js date.js 而且感觉非常程序化,基本上就
当我运行 git clean --dry-run 时,结果有点像: Would remove an_untracked_file Would remove an_untracked_file_2 Wo
嘿,第一次在 Stack Overflow 上提问,所以请放轻松! 我最近开始开发一个 CMS 驱动的网站,该网站需要多语言功能(12 种语言!)。我过去曾推出过 Expression Engine/
我正在使用可移植类库构建 Android/iOS xamarin 表单应用程序。我正在寻找在 PCL 项目中执行此示例的最佳方法: https://msdn.microsoft.com/en-us/l
我经常听到有关"new"MV* 框架的信息。我修改了 KnockoutJS,创建了一个发票应用程序,但我更喜欢用原始 JavaScript 编写干净、模块化的代码——必要时利用实用程序 API 和其他
我有这段 javascript 代码,当我点击按钮时, Canvas 会被清除。 但是当我移动鼠标时, Canvas 会显示我之前写的内容,而且它不会以空白 Canvas 开始 单击按钮后如何从空白
我有一个带有 5 个内部字符串变量的对象,但其中 3 个是可选的。我可以为每个可能的组合创建一个构造函数,或者我可以调用通用构造函数并向其传递一些空字符串。后一种情况对我来说很有趣,如果我在调用构造函
我是 SQL 的新手。我正在尝试从数据库 (Postgres) 获取数据,如果这些数据无效,则即时替换它们。是否可以使用纯 SQL 来执行此操作?例如,在我的数据库 users 中,我有包含以下数据的
当我清理 TOMCAT 或清理 tomcat 工作目录时,我丢失了保存在 Tomcat 文件夹中的所有文件,我可以禁用此选项吗? 最佳答案 清理 tomcat 工作目录将清除部署到 Tomcat 中的
我正在清理我的一个旧项目。它必须做的一件事是——给定笛卡尔网格系统和网格上的两个正方形,找到所有正方形的列表,连接这两个正方形中心的线将通过这些正方形。 这里的特殊情况是所有起点和终点都被限制在正方形
我现在正在学习如何使用 makefile 并制作了以下 makefile(我在 Windows 上使用 visual studio 命令行编译器) CC = cl CFLAG = /EHsc test
我做了 git checkout master。如果我执行 git status 它会在我的工作目录中显示两个更改的文件,即使我没有碰过它们。这似乎是某种行尾问题。 git reset --hard
在我看来,Makefile 规则大致可以分为“积极”和“消极”规则:“积极”规则创建丢失或更新过时的文件,而“消极”规则删除文件。 为“肯定”规则编写先决条件非常简单:如果目标和先决条件是文件名,ma
我的电脑上安装了 WAMP,我想在其中运行 Drupal 6。 当我安装 Drupal 时,我可以选择激活 Clean URL。 首先,我将 Drupal 安装放在 www 文件夹中,我可以选择启用干
考虑以下堆栈跟踪: In [3]: f.clean() ------------------------------------------------------------------------
我放弃了。我已经阅读了这里的几十个问题,甚至问了我自己的问题,我尝试了很多事情,我只是不知道该怎么做。 我需要使用以下格式创建 url:(NSFW 链接,请注意) http://jbthehot.co
下面的代码是我目前的解决方案。 我试图模仿的一个很好的例子是 FrameworkElement.ActualWidth 属性。您知道 ActualWidth 属性是如何计算和重新分配的,每当 Widt
当然,Ruby 确实有递归,就像任何其他高级编程语言一样。只要递归深度不是太高,这就可以正常工作,但如果是,您将捕获堆栈溢出: #!/usr/bin/ruby2.0 def rec_naive(i)
我找到的最短方法是: n = 5 # Python 2. s = str(n) i = int(s) # Python 3. s = bytes(str(n), "ascii") i = int(s)
这是一种经常出现的情况,对我来说永远不会太容易。我想我会问其他人如何处理它。 想象一下,如果 demo=60 命令行参数的处理是这样完成的: if DemoOptionSpecified() {
我是一名优秀的程序员,十分优秀!