- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的场景是这样的:
我当前的解决方案:让所有工作人员通过另一个队列回答哪些任务已完成,并引入必须完成任务的截止日期。如果达到截止日期,则重置任务并重新排队。这存在解决方案“软”的问题,即截止日期是任意的。
我正在寻找最简单的解决方案。是否有更简单或更严格的解决方案?
最佳答案
此解决方案使用三个队列来跟踪工作(模拟为 WORK_ID
):
todo_q
:任何要完成的工作(包括如果进程在运行中死亡则要重做的工作)start_q
:任何已经被进程启动的工作finish_q
:任何已经完成的工作使用这种方法你不需要定时器。只要您分配一个进程标识符并跟踪分配,检查是否 Process.is_alive()
。如果进程终止,则将该工作添加回待办事项队列。
在下面的代码中,我模拟了一个工作进程在 25% 的时间内死亡...
from multiprocessing import Process, Queue
from Queue import Empty
from random import choice as rndchoice
import time
def worker(id, todo_q, start_q, finish_q):
"""multiprocessing worker"""
msg = None
while (msg!='DONE'):
try:
msg = todo_q.get_nowait() # Poll non-blocking on todo_q
if (msg!='DONE'):
start_q.put((id, msg)) # Let the controller know work started
time.sleep(0.05)
if (rndchoice(range(3))==1):
# Die a fraction of the time before finishing
print "DEATH to worker %s who had task=%s" % (id, msg)
break
finish_q.put((id, msg)) # Acknowledge work finished
except Empty:
pass
return
if __name__ == '__main__':
NUM_WORKERS = 5
WORK_ID = set(['A','B','C','D','E']) # Work to be done, you will need to
# name work items so they are unique
WORK_DONE = set([]) # Work that has been done
ASSIGNMENTS = dict() # Who was assigned a task
workers = dict()
todo_q = Queue()
start_q = Queue()
finish_q = Queue()
print "Starting %s tasks" % len(WORK_ID)
# Add work
for work in WORK_ID:
todo_q.put(work)
# spawn workers
for ii in xrange(NUM_WORKERS):
p = Process(target=worker, args=(ii, todo_q, start_q, finish_q))
workers[ii] = p
p.start()
finished = False
while True:
try:
start_ack = start_q.get_nowait() # Poll for work started
## Check for race condition between start_ack and finished_ack
if not ASSIGNMENTS.get(start_ack[0], False):
ASSIGNMENTS[start_ack[0]] = start_ack # Track the assignment
print "ASSIGNED worker=%s task=%s" % (start_ack[0],
start_ack[1])
WORK_ID.remove(start_ack[1]) # Account for started tasks
else:
# Race condition. Never overwrite existing assignments
# Wait until the ASSIGNMENT is cleared
start_q.put(start_ack)
except Empty:
pass
try:
finished_ack = finish_q.get_nowait() # Poll for work finished
# Check for race condition between start_ack and finished_ack
if (ASSIGNMENTS[finished_ack[0]][1]==finished_ack[1]):
# Clean up after the finished task
print "REMOVED worker=%s task=%s" % (finished_ack[0],
finished_ack[1])
del ASSIGNMENTS[finished_ack[0]]
WORK_DONE.add(finished_ack[1])
else:
# Race condition. Never overwrite existing assignments
# It was received out of order... wait for the 'start_ack'
finish_q.put(finished_ack)
finished_ack = None
except Empty:
pass
# Look for any dead workers, and put their work back on the todo_q
if not finished:
for id, p in workers.items():
status = p.is_alive()
if not status:
print " WORKER %s FAILED!" % id
# Add to the work again...
todo_q.put(ASSIGNMENTS[id][1])
WORK_ID.add(ASSIGNMENTS[id][1])
del ASSIGNMENTS[id] # Worker is dead now
del workers[id]
ii += 1
print "Spawning worker number", ii
# Respawn a worker to replace the one that died
p = Process(target=worker, args=(ii, todo_q, start_q,
finish_q))
workers[ii] = p
p.start()
else:
for id, p in workers.items():
p.join()
del workers[id]
break
if (WORK_ID==set([])) and (ASSIGNMENTS.keys()==list()):
finished = True
[todo_q.put('DONE') for x in xrange(NUM_WORKERS)]
else:
pass
print "We finished %s tasks" % len(WORK_DONE)
在我的笔记本电脑上运行这个...
mpenning@mpenning-T61:~$ python queueack.py
Starting 5 tasks
ASSIGNED worker=2 task=C
ASSIGNED worker=0 task=A
ASSIGNED worker=4 task=B
ASSIGNED worker=3 task=E
ASSIGNED worker=1 task=D
DEATH to worker 4 who had task=B
DEATH to worker 3 who had task=E
WORKER 3 FAILED!
Spawning worker number 5
WORKER 4 FAILED!
Spawning worker number 6
REMOVED worker=2 task=C
REMOVED worker=0 task=A
REMOVED worker=1 task=D
ASSIGNED worker=0 task=B
ASSIGNED worker=2 task=E
REMOVED worker=2 task=E
DEATH to worker 0 who had task=B
WORKER 0 FAILED!
Spawning worker number 7
ASSIGNED worker=5 task=B
REMOVED worker=5 task=B
We finished 5 tasks
mpenning@mpenning-T61:~$
我以 25% 的死亡率对 10000 多个工作项进行了测试。
关于python - 恢复丢失的 multiprocessing.Queue 项目,当工作进程死亡时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8532215/
我使用适用于 Windows 的 QuickBooks。并且 Windows 应用程序调用我的后端,在某些库脚本中它调用 exit 或 die ...所以我无法捕获响应,需要检测退出运行的位置或在退出
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我很无聊,只有 30 分钟的空闲时间,所以我决定尝试一下制作生活游戏。我在维基百科上遵循了该规则,但它似乎无法正常工作。有人可以告诉我我会做错什么吗? 规则如下: 任何少于两个活邻居的活细胞都会死亡,
我的社交网络上有一个简单的插入查询,允许用户在文本区域中输入文本并将其输出到他们的个人资料页面上。他们可以选择删除,并按预期将状态标记为“死亡”,并删除更新。问题是,如果他们只是输入一个新的内容,而不
这可能是一个硬件问题,因为我不确定后台 worker 是如何实现的,但问题是:我有 3 个后台 worker 运行不同的线程。我对这些线程进行了编码,以便在它们开始和结束时显示,但我得到了一些非常奇怪
我有一个简单的服务器: from multiprocessing import Pool, TimeoutError import time import os if __name__ == '__m
在这里,我尝试在线程终止后加入该线程,代码工作正常,但我的问题是它不应该抛出一些错误消息或任何信息吗? public class MultiThreadJoinTest implements Runn
我正在开发一个简单的 Android 项目,但遇到了可怕的致命异常,并且确实不知道如何确定我是否在 Android 世界中做一些越界的事情...... 我有这个代码: private OnClickL
我正在尝试编写一个程序,根据用户输入值“n”,我将 fork 那么多进程以同时运行。此外,每个 child 都试图执行我创建的另一个文件,这将生成 x sleep 时间和 x 退出值。最终,当 chi
我们知道,当系统资源耗尽时,后台 Activity 会序列化其状态并被操作系统杀死。当我们恢复它时,操作系统通过传递给 onCreate 方法的 savedInstanceState 恢复 Activ
我想这样做是为了测试我的代码。我想我可以围绕弱引用对象制作另一个包装器,但更愿意直接工作以模拟原始对象被回收。 这是我目前的代码 var myString = "someString"; var
我使用 GCM 在发布图片时收到通知,然后我下载并处理它: public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
我有一个带有中央事件机制的程序,该机制使用 select、epoll 或 kevent(平台依赖、OSX、Linux 和 FreeBSD)。 现在我有一个问题,我需要等待一个进程完成执行。我从这个过程
我有一个非常简单的函数,如下所示: public static boolean isAppInstalled(String packageName) { PackageManager pm =
我有一个接受图像复制/粘贴的 TinyMCE 表单。输入完评论后,按“发布”,它会提交表单,解析内容并显示在屏幕对话中。 我正在尝试使用 preg_match_all 从 POSTed 变量中提取 b
这是我在 vs 代码中的交互式窗口中运行代码时显示的错误消息: C:\Users\rohit\AppData\Roaming\Python\Python38\site-packages\traitle
在 Scala 中,当另一个(远程)actor 终止时,可以通过设置 trapExit 标志并使用第二个 actor 作为参数调用 link() 方法来通知一个 actor。在这种情况下,当远程参与者
我正在tpot上运行dask在gcp的kubernetes集群上运行,该集群是24核120 GB内存,带有4个kubernetes节点,我的kubernetes yaml是 apiVersion: v
几周来我一直在为这个问题苦苦挣扎。我对 Android 还很陌生,希望您能帮助我。 我有这个服务,它运行在与应用程序不同的线程上。本质上,用户指示它启动,并且它应该保持 Activity 状态,直到用
我正在编写一个插件,它从不和谐中获取消息并将其发送到我的世界服务器。Minecraft 客户端很难渲染表情符号。因此我选择使用https://github.com/kcthota/emoji4j将所有
我是一名优秀的程序员,十分优秀!