JFについて詳しく説明する
スレッド化に関する私の一般的なアドバイスは、絶対に必要な場合にのみ導入することです。
- 文字通り低レベルの I/O をブロックしており、ネイティブ スレッドを使用する以外に方法はありません。
- あなたは計算の限界に達しており、より多くのコアを利用する必要があります。その場合、Python はGILであるため、とにかくあなたに不利に働く可能性があります。
別の方法として、イベントのスケジューリングにネイティブ スレッドに依存しない、twistedやgeventなどのスケジューラを提供するライブラリを利用します。
イベント
スレッド モデルを念頭に置いた方法でゲームを作成できますが、スレッド間のリソース競合について心配する必要はありません。あなたの例では、 sleepのようなさまざまな関数の gevent バージョンを使用することに注意する必要があります。
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()
ツイスト リアクターは、何もすることがなくなったときにシャットダウンしないことに注意してください。これは、明示的にプログラマーに任されています。
ローリング・ユア・オウン
学習目的で独自のスケジューラーを作成することは興味深いことかもしれませんし、それを必要とする公平性などの要件がゲームにあるかもしれません。良い出発点は、インスピレーションを得るために別の最小限のスケジューラーを調べることです。