【问题标题】:Need Help Combining time.sleep with multiprocessing in python 3需要帮助将 time.sleep 与 python 3 中的多处理相结合
【发布时间】:2012-10-27 02:05:40
【问题描述】:

使用 python 3 制作回合制游戏。我想要 2 个角色(敌人和敌人)攻击,根据随机 + 速度暂停,如果他们还活着,则再次攻击。

我遇到的问题是 time.sleep 冻​​结了两个模块,而不是 1 或另一个。有什么建议可以有效地完成这项工作吗?

from multiprocessing import Process
import time
import random

def timing1():  
    speed=60#SPEED IS NORMALLY A KEY FROM LIST, USING 60 FOR EXAMPLE  
    sleeptime=36/((random.randint(1,20)+speed)/5)  
    print (sleeptime)  
    time.sleep(sleeptime)  
    input('HERO ACTION')  

def timing2():  
    speed=45  
    sleeptime=36/((random.randint(1,20)+speed)/5)  
    print (sleeptime)  
    time.sleep(sleeptime)  
    input('FOE ACTION')  

if __name__ == '__main__':  
    p1=Process(target=timing1)  
    p1.start()  
    p2=Process(target=timing2)  
    p2.start()  
    p1.join()  
    p2.join()

【问题讨论】:

    标签: process python-3.x sleep


    【解决方案1】:

    详细说明 J.F.

    我对线程的一般建议是仅在绝对必要时才引入它。

    • 您实际上是在低级 I/O 上阻塞,除了使用本机线程之外别无选择。
    • 您正在达到计算限制,需要使用更多内核,在这种情况下,python 由于它的 GIL 可能对您不利。

    作为替代方案,使用提供诸如 twisted 或 gevent 之类的调度程序的库,该库不依赖本机线程来调度事件。

    gevent

    您可以在编写游戏时考虑到线程模型,而不必担心线程之间的资源争用。 您必须记住在您的示例中使用 various functions 的 gevent 版本,例如 sleep。

    import random
    import gevent
    
    
    def hero():
        speed = 60
        sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
        print (sleeptime)
        gevent.sleep(sleeptime)
        input('HERO ACTION')
    
    
    def foe():
        speed = 45
        sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
        print (sleeptime)
        gevent.sleep(sleeptime)
        input('FOE ACTION')
    
    
    if __name__ == "__main__":
        heroThread = gevent.Greenlet(hero)
        foeThread = gevent.Greenlet(foe)
    
        heroThread.start()
        foeThread.start()
    
        gevent.joinall([heroThread, foeThread])
    

    扭曲

    提供一个事件反应器,它是用纯 python 编写的,并且不假装比单线程事件反应器(又名Event Loop)更多或更少。 这将需要对您的示例进行更大程度的重写。

    import random
    from twisted.internet import reactor
    
    
    def heroAction():
        input('HERO ACTION')
    
    
    def heroStart():
        speed = 60
        sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
        print (sleeptime)
        reactor.callLater(sleeptime, heroAction)
    
    
    def foeAction():
        input('FOE ACTION')
    
    
    def foeStart():
        speed = 45
        sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
        print (sleeptime)
        reactor.callLater(sleeptime, foeAction)
    
    
    if __name__ == "__main__":
        # Call when the reactor has started.
        reactor.callWhenRunning(heroStart)
        reactor.callWhenRunning(foeStart)
        reactor.run()
    

    请注意,扭曲反应堆在无事可做时不会关闭,这是明确留给程序员的。

    自己动手

    出于学习目的编写自己的调度程序可能会很有趣,或者您的游戏中可能有一些要求,例如需要它的公平性。 一个很好的起点是查看another minimalistic scheduler 以获得灵感。

    【讨论】:

      【解决方案2】:

      转一圈后,进程会在您的代码中退出。您的主进程通过调用.join() 等待两个进程退出,即time.sleep() 不会冻结其他进程。

      在timing*() 函数顶部添加while True: 以进行多次移动。

      这里不需要多个进程。您可以使用线程甚至单个线程来实现转弯。

      【讨论】:

      • 谢谢。这方面的新手,但要坚持下去。
      猜你喜欢
      • 2020-06-29
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 2014-05-18
      • 1970-01-01
      相关资源
      最近更新 更多