我的代码是:
类客户端(DirectObject,对象):
'''
Clientclass. This class processes the keys which the user presses to the host and gets the data
from the host, which are to be set in a dummy version of the model
'''
seed= ""
id = None
def __init__(self, ip):
'''
This is the constructor. It creates the ShowBase an starts both the process which processes the keys and the process
which takes in data from the host
param: ip ip is a float which contains the ip adress of the host
'''
logging.getLogger(__name__).info("Clientobjekt erstellt")
self.makw = mouseAndKeyWrapper.MouseAndKeyWrapper()
time.sleep(5)
from modules.logic import game
self.cprocess = threading.Thread(target = Client.workAsClient, args = (ip,self.makw))
self.cprocess.start()
time.sleep(5)
while True:
if Client.seed != "":
break
game.seed = Client.seed
game.initGame()
game.initGameInstance()
game.start()
self.workShowBase()
game.myShowBase.run()
def workShowBase(self):
'''
workShowBase defines how to change values in keydict when keys are pressed and
starts ShowBase process
'''
from modules.logic import game
logging.getLogger(__name__).info("Showbase is working")
game.myShowBase.accept("w", self.makw.setKeys, ["w",1])
game.myShowBase.accept("a", self.makw.setKeys, ["a",1])
game.myShowBase.accept("s", self.makw.setKeys, ["s",1])
game.myShowBase.accept("d", self.makw.setKeys, ["d",1])
game.myShowBase.accept("space", self.makw.setKeys, ["space",1])
game.myShowBase.accept("w-up", self.makw.setKeys, ["w",0])
game.myShowBase.accept("a-up", self.makw.setKeys, ["a",0])
game.myShowBase.accept("s-up", self.makw.setKeys, ["s",0])
game.myShowBase.accept("d-up", self.makw.setKeys, ["d",0])
game.myShowBase.accept("space-up", self.makw.setKeys, ["space",0])
#game.myShowBase.accept("mouse1",self.makw.setKeys,["mouse",1])
#game.myShowBase.accept("mouse1-up",self.makw.setKeys,["mouse",0])
@staticmethod
def workAsClient(ip, makw):
'''
This method contains the client thread, that is, the thread which sends data to the host and
receives data from it - for this reason it has to be static
param: ip ip is a float which contains the ip adress of the host
'''
logging.getLogger(__name__).info("Clientendlosschleife gestartet")
from modules.logic import game
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, 50001))
seedSend = s.recv(4096)
Client.seed =loads(seedSend)
ID = s.recv(4096)
Client.id = loads(ID)
makw.id = id
keyThread = threading.Thread(target =Client.sendData, args = (makw,s))
print("threadmade")
keyThread.start()
print("started")
@staticmethod
def sendData(makw, sock):
print("method")
while True:
print("loop")
dictToSend = dumps(makw,2)
print("dumped")
sock.sendall(dictToSend)
print("sent")
这确实工作得很好。
但是,如果我在构造函数中省略“time.sleep(5)”, 调用 sendData 的线程从未创建过,更不用说启动了。 怎么可能?从技术上讲,Showbase 不应该干涉,因为它处于另一个进程中! 我可以解决这个问题吗?
最佳答案
您应该避免使用完全主动等待,这可能会消耗所有资源,让其他线程没有机会工作。
所以你最好尝试一下:
while True:
if Client.seed != "":
break
time.sleep(10)
确实,您的辅助线程已启动,但如果所有处理都由主线程在其无限循环中消耗,它将永远没有机会工作,然后永远不会提供主线程正在等待的种子=> 死锁
当您使用 sleep(5) 时,您有机会调度辅助线程并生成种子;然后,当后者重新安排主线程时,它会找到种子,继续工作,一切都会按预期进行。
但是您的解决方法非常脆弱,因为您无法保证在主线程休眠期间会调度另一个线程。
它现在可以在您的开发环境中运行,但稍后可能会在另一个环境中的生产中中断。
关于python - 线程显然在没有任何代码引用的情况下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14282505/