简体   繁体   中英

why are my python threads blocking each other

My current predicament is that I attempted to make a blocking web serving script non blocking to allow for more than one download to take place at any one time but currently it will hang and wait for the first download to complete before starting the second. Before you go out of your way to down vote this because the answer is odious please know that this is my first ever python script and I am self teaching.

In the example below I only post a single "ConnectionProcesser" Because they all contain the same code if you need more code please just ask

The script has 3 dependinces

import socket  # Networking support
import signal  # Signal support (server shutdown on signal receive)
import threading #to make the thing run more than one at a time

Please note that the script has been edited and quite a bit of the code is missing but I believe that it is unrelated to the problem.

 def ConnectionProcessorC(self):
     connC, AddressC = self.socket.accept()
     print("C Got connection from:", AddressC)
     DataRecivedC = connC.recv(1024) #receive data from client
     DataRecivedC = bytes.decode(DataRecivedC) #decode it to string
     print(DataRecivedC)
     RequestMethod = DataRecivedC.split(' ')[0]
     print ("C Method: ", RequestMethod)
     if (RequestMethod == 'GET') | (RequestMethod == 'HEAD'):
         Response_Headers = 'HTTP/1.1 200 OK\n'
        # Current_Date = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
        # Response_Headers += 'Date: ' + current_date +'\n'
         Response_Headers += 'Server: Moes-Python-Server\n'
         Response_Headers += 'Connection: close\n\n'  # signal that the conection wil be closed after complting the request
         Server_Response =  Response_Headers.encode() # return headers for GET and HEAD
         file_handler = open('/usr/share/nginx/html/100mb.dump','rb')
         Response_Content = file_handler.read() # read file content
         file_handler.close()
         URL=DataRecivedC.split(' ')
         URL = URL[1] # get 2nd element
         #Response_Content="<html><body><p>Charlie TEStin this stuff yehURL:"+URL+"</p></body></html>"
         Server_Response +=  Response_Content 

         connC.send(Server_Response)
         print ("C Closing connection with client")
     else:
         print("C Unknown HTTP request method:", RequestMethod)

     connC.close()
     return 
 def Distrabuteconnections(self):
     A=0
     """ Main loop awaiting connections """
     while True:
         print ("Awaiting New connection")
         self.socket.listen(10) # maximum number of queued connections #changed to 1 from 3 to try and prevent waiting after closing for ther que to clean up 

         if (A==0):
             ConnectionProcessorA = threading.Thread(target=self.ConnectionProcessorA())
             ConnectionProcessorA.start()
             A=1
         elif (A==1):
             ConnectionProcessorB = threading.Thread(target=self.ConnectionProcessorB())
             ConnectionProcessorB.start()
             A=2
         else:
             ConnectionProcessorC = threading.Thread(target=self.ConnectionProcessorC())
             ConnectionProcessorC.start()
             A=0

I think that the problem could be solved by changing while true to something that loops 3 times instead of one.

You should pass a reference to the method you wish to start in a thread. Instead, you are calling the thread, and passing the data returned from that method to the threading.Thread() call.

In short your code should become:

     if (A==0):
         ConnectionProcessorA = threading.Thread(target=self.ConnectionProcessorA)
         ConnectionProcessorA.start()
         A=1
     elif (A==1):
         ConnectionProcessorB = threading.Thread(target=self.ConnectionProcessorB)
         ConnectionProcessorB.start()
         A=2
     else:
         ConnectionProcessorC = threading.Thread(target=self.ConnectionProcessorC)
         ConnectionProcessorC.start()
         A=0

Note the removal of the brackets after self.ConnectionProcessorA etc. This passes a reference to the method to start in the thread, which the threading module will call itself.

Note, it is recommended to store a reference to the thread you create so that it doesn't get garbage collected. I would thus recommend your code becomes:

     if (A==0):
         self.cpa_thread= threading.Thread(target=self.ConnectionProcessorA)
         self.cpa_thread.start()
         A=1
     elif (A==1):
         self.cpb_thread= threading.Thread(target=self.ConnectionProcessorB)
         self.cpb_thread.start()
         A=2
     else:
         self.cpc_thread= threading.Thread(target=self.ConnectionProcessorC)
         self.cpc_thread.start()
         A=0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM