Question

My Code is:

class Client(DirectObject, object):

'''
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")

That does work fine.

However, if I omitt "time.sleep(5)" in the constructor, the thread which calls sendData is never ever made, let alone be started. How can that be? Showbase technically should not interfere, being in another process! Can I fix this?

Was it helpful?

Solution

You should avoid using full active waiting that may consume all the resources letting no chance for other threads to work.

So you may better try :

while True:
        if Client.seed != "":
            break
        time.sleep(10)

Indeed your secondary thread is launched but if all processing is consumed by your main thread in its infinite loop it will never have a chance to work, then never providing the seed for which the main thread is waiting => deadlock

When you use sleep(5) you give a chance to the secondary thread to be scheduled and to produce the seed; then when latter the main thread is rescheduled it finds the seed, continues working and all is going as expected.

But your workaround is very brittle because you have no guarantee that during the sleep of the main thread the other one will be scheduled.

It works now in your development environment but may break later in production in another context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top