threading issue

I am putting together a threaded client/server program, which shows current throughput on the server screen.

The server receives the client connect and a thread is being spun up. That portion works just fine.

  • Client connect: Server says hello to client
  • The server starts a thread
  • The Client keeps on sending the the tx/rx info
  • Server shows the output on the screen

So far so good...

Here is the program, I want to keep track of the average for a specific period of time.

the class for the client:

class client(object):
    def __init__(self, name):
        self.name=name
        self.txtotal=0
        self.rxtotal=0
    def txrxinc(self, tx, rx):
        self.txtotal+=tx
        self.rxtotal+=rx
    def print_average(self):
        while True:
            time.sleep(AVERAGE)
            lock.acquire(True)
            rx_bytes, rx_kbytes, rx_mbytes=converter(self.rxtotal/AVERAGE)
            tx_bytes, tx_kbytes, tx_mbytes=converter(self.txtotal/AVERAGE)
            print socket.gethostbyaddr(clientaddress[0])[0]+"("+clientaddress[0]+")", "Average:", rx_bytes, rx_kbytes, rx_mbytes, tx_bytes, tx_kbytes, tx_mbytes
            self.txtotal=0
            self.rxtotal=0
            lock.release()

As you can see, "while True:" keeps on looping as its own thread. Every time the time.sleep(AVERAGE) hits, it is supposed to print out the average on the screen.

Now, the above function gets called like this. I will only show the first couple of lines, because it just hangs with "while True:" in place

def replyback(clientsocket, clientaddress):
    CLIENTS[clientaddress[0]]=client(clientaddress[0])
    ThroughPutThread=threading.Thread(target=CLIENTS[clientaddress[0]].print_average())
    ThroughPutThread.daemon=True
    ThroughPutThread.start()
    print CLIENTS

"print CLIENTS" gets never started, if the "while True:" loop is active. If I take "while True:" out, we only run "print_average" once and the server keeps on getting all the client rx/tx info.

In short, If I disable the loop, everything works.

I am not sure what I am doing wrong.... It's like it is not running as a thread.

12 comments · 100% upvoted · other discussions

comments

JohnnyJordaan

Can you explain why you are running threads this way? Why not consider a client object a thread by itself?

class MyClient(threading.Thread):
    def __init__(self, name):
        super(MyClient, self).__init__()
        self.name=name
        self.daemon=True
        self.txtotal=0
        self.rxtotal=0
    def txrxinc(self, tx, rx):
        self.txtotal+=tx
        self.rxtotal+=rx
    def run(self):
        while True:
            time.sleep(AVERAGE)
            with lock:
                rx_bytes, rx_kbytes, rx_mbytes=converter(self.rxtotal/AVERAGE)
                tx_bytes, tx_kbytes, tx_mbytes=converter(self.txtotal/AVERAGE)
                print socket.gethostbyaddr(clientaddress[0])[0]+"("+clientaddress[0]+")", "Average:", rx_bytes, rx_kbytes, rx_mbytes, tx_bytes, tx_kbytes, tx_mbytes
                self.txtotal=0
                self.rxtotal=0

def replyback(clientsocket, clientaddress):
    ThroughPutThread=Client(clientaddress[0])
    ThroughPutThread.start()
    CLIENTS[clientaddress[0]] = ThroughPutThread
    print CLIENTS

I'm still wondering what the context of all this is, so if you could share your full code we can give more feedback I think.

StorageNinja [OP]

oohhhhh... I think i know what you are getting at, but would that really make a difference? Does it make a difference, if just a method or the entire object a thread is?

JohnnyJordaan

Not per se, but calling an object's method as a Thread is kinda strange. My experience is that if you keep your code intuitive and clear, you won't run into many mysterious behaviours like this one.

Maybe it won't fix the problem directly but at least it's a good start.