暂停和恢复功能

问题描述:

我正在Python中编写一个bot,并“人性化”它,我需要随机暂停和恢复函数。 只能在某些定义的点处暂停和恢复功能。暂停和恢复功能

僵尸制成的各种功能,如

do_action1(*args) 
do_action2(*args) 
do_action3(*args) 
... 
start_bot() 
stop_bot() 

功能start_bot()调用do_action1()do_action2(),...为了和给他们*args
我需要找到一种方法来随机启动do_actionX()功能,在某些点暂停并运行另一个随机do_actionX()函数,那么暂停和恢复前一个等等...

要随机启动的功能我我以为我可以使用里面有函数的字典并随机选择其中的一个。

我想我可以用线程做到这一点,但由于我的机器人正在使用多处理,它会是一个正确的选择使用多线程和多处理?
我使用多处理器同时运行多个机器人,并通过链接到接口的主Python脚本来管理它们。每个bot实例都连接到一个不同的帐户。

如果我使用多线程,我该如何使函数停止在某些定义点而不是随机?

例如:

def do_action1(*args): 
    print("something") 
    # do something else 
    # <--- at this point the function could be paused 
    print("something") 
    # <--- at this pint the function cannot be paused! 
    print("else") 
    # <--- and here the function could be paused again 

的倍的功能将被暂停必须是随机的。有没有办法做到这一点?
线程是否正确解决此问题?

+3

为什么不使用函数内部的yield来暂停?如果没有其他功能需要运行,请调用相同的功能。这将使它成为每个机器人的一个线程 – user1827356

+1

请参阅[关于协程和并发的好奇课程](http://www.dabeaz.com/coroutines/) –

您可以使用yield关键字来创建协同例程。这里有一个例子:

import random 
random.seed() 

def do_action1(): 
    print("Hello") 
    yield 
    print("HELLO!") 
    yield 
    print("hello?") 
def do_action2(): 
    print("Are you there?") 
    yield 
    print("ARE YOU THERE!") 
    yield 
    print("I'm scared.") 
def do_action3(): 
    print("Is somebody out there?") 
    yield 
    print("SOMEBODY IS OUT THERE!") 
    yield 
    print("I'm dead.") 

def bot(*actions): 
    actions = [action() for action in actions] 
    while actions: 
     action = random.choice(actions) 
     try: 
      next(action) 
     except StopIteration: 
      actions.remove(action) 
    return 

bot(do_action1, do_action2, do_action3) 
+0

谢谢。我会尽力实现你的代码:) – GroovyTony

线程是一个好办法。要暂停功能,使用time.sleep()(基于How can I make a time delay in Python?):

import time, random 

# Time range to sleep, in seconds 
def randomWait(): 
    sleepMin = 1.0 
    sleepMax = 5.0 
    time.sleep(random.uniform(sleepMin, sleepMax)) 

def do_action1(*args): 
    print("something") 
    # do something else 
    randomWait() 
    print("something") 
    print("else") 
    randomWait() 

我在这个例子中使用random.uniform,但你可以自由地进行时间间隔为花哨的随机性,你想使用random模块或任何你喜欢的东西。

线程化解决方案将允许不同的操作同时运行。如果你不想让这种情况,使用一个单独的线程,并使用yield为user1827356提示:

import time, random 

# Time range to sleep, in seconds 
def randomWait(): 
    sleepMin = 1.0 
    sleepMax = 5.0 
    time.sleep(random.uniform(sleepMin, sleepMax)) 

def do_action1(*args): 
    print("something") 
    # do something else 
    yield 
    print("something") 
    print("else") 

# Other actions defined similarly 

actions = [do_action1(), do_action2(), do_action3()] 
while actions: 
    randomWait() 
    action = random.choice(actions) 
    try: 
     next(action) 
    except StopIteration: 
     actions.remove(action) 

注意,在这种情况下,你的行为是发电机。它们基本上是运行您定义的代码并存储状态(暂停)的对象,只要它们碰到yield关键字。对于单线程应用程序,这可能是最好的方法。

+0

您尚未正确复制@Robᵩ的答案。你不会调用这些动作,所以他们永远不会达到第一个“收益”。 –

+0

感谢您的收获。我没有复制罗布,虽然他确实首先发布了这个部分。我的回答在编辑之前有StopIteration捕获。 –