为什么我的python线程互相阻塞
我目前的困境是我试图做一个阻塞的web服务脚本非阻塞,以允许在任何时候发生多个下载,但目前它会挂起并等待首先下载完成后再开始第二个。在你投票决定之前,因为答案是可恶的,请知道这是我第一次使用python脚本,我是自学教程。为什么我的python线程互相阻塞
在下面的例子中我只发布一个“ConnectionProcesser”因为它们都含有相同的代码 如果你需要更多的代码,请只问
脚本有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
请注意该脚本已被编辑,并且相当一部分代码已丢失,但我认为它与该问题无关。
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
我认为这个问题可以通过改变来解决,而真正的事情是循环3次而不是一次。
你应该传递一个你想在线程中启动的方法的引用。相反,您正在调用线程,并将从该方法返回的数据传递给threading.Thread()
调用。
总之你的代码应该变成:
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
注self.ConnectionProcessorA
等后去掉括号这传递给方法的引用的线程,线程模块调用自身开始。
请注意,建议存储对您创建的线程的引用,以避免垃圾收集。因此,我建议你的代码变成:
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
我试过你的代码,它所做的一切都是反复运行ConnectionProcessorA,所以我无法测试它是否有效 – door 2014-10-12 00:46:17
我认为我需要做的是删除while while true,并在创建连接时使用线程内部的调用替换它,以便脚本不会像创建线程一样继续创建线程 – door 2014-10-12 00:50:01
我会期望所有3个线程仍然运行,但是最好每次建立连接时都生成一个线程。可能你可以在主线程中调用'socket.accept()',并将'connX'和'AddressX'变量传递给线程。如果您需要帮助改变程序的架构,最好用一个**最小化的工作示例**发布一个新问题,以便您可以真正运行一些代码来模拟您正在做的事情。 – 2014-10-12 03:48:48
从线程切换到子进程应该解决它 – 2014-10-12 00:25:05
但为什么我需要的子进程是有什么原因?他们不跑得慢吗? – door 2014-10-12 00:26:09
子进程可能需要更长的时间才能启动并且内存占用量更高,但没有理由为什么它们会变慢。原因将是GIL,这似乎干扰线程。这不在子流程中发生。 – 2014-10-12 00:27:43