详细说明 JF
我对线程的一般建议是仅在绝对必要时才引入它。
- 您实际上是在低级 I/O 上阻塞,除了使用本机线程之外别无选择。
- 您正在达到计算限制并且需要使用更多内核,在这种情况下,由于它的GIL的 python可能对您不利。
作为替代方案,使用一个库,该库提供一个调度程序,如twisted或gevent,它不依赖本机线程来调度事件。
事件
您可以在编写游戏时考虑到线程模型,而不必担心线程之间的资源争用。您必须记住在您的示例中使用各种功能的 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 编写的,并且不假装比单线程事件反应器(又名事件循环)更多或更少。这将需要对您的示例进行更大的重写。
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()
请注意,扭曲反应堆在无事可做时不会关闭,这是明确留给程序员的。
滚动你自己的
出于学习目的编写自己的调度程序可能会很有趣,或者您可能在游戏中有要求,例如需要它的公平性。一个很好的起点是从另一个简约的调度程序中寻找灵感。