暂停并恢复功能

时间:2015-12-02 20:27:58

标签: python multithreading random artificial-intelligence

我正在用python编写一个机器人并“人性化”它我需要随机暂停和恢复功能。 只能在某些定义的点上暂停和恢复功能。

机器人由各种功能组成,如

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

函数暂停的时间必须是随机的。有没有办法做到这一点?
线程是解决此问题的正确方法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用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)

答案 1 :(得分:0)

线程是一种很好的方法。要暂停此功能,请使用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,因为用户1827356建议:

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关键字时存储状态(暂停)。对于单线程应用程序,这可能是最好的方法。