Python 同时从多个线程调用.net库中的方法时,结果不完整
我正在开发一个GUI,它显示我们工厂中某些工具的状态。可以通过集成到.dll文件中的webservice请求状态。启动GUI应用程序时,我希望同时请求所有工具的状态。为此,我为每个工具创建一个线程,然后调用一个方法来获取工具的状态。我得到了一些正确的响应,但大约一半的线程根本不提供响应,有些线程返回错误的值 如果我一个接一个地运行请求,一切都会很好。但这需要很长时间Python 同时从多个线程调用.net库中的方法时,结果不完整,python,multithreading,Python,Multithreading,我正在开发一个GUI,它显示我们工厂中某些工具的状态。可以通过集成到.dll文件中的webservice请求状态。启动GUI应用程序时,我希望同时请求所有工具的状态。为此,我为每个工具创建一个线程,然后调用一个方法来获取工具的状态。我得到了一些正确的响应,但大约一半的线程根本不提供响应,有些线程返回错误的值 如果我一个接一个地运行请求,一切都会很好。但这需要很长时间 def request_states(self, resource, i): # self.driver.GetToolS
def request_states(self, resource, i):
# self.driver.GetToolState is a specific method defined in a dll
# it accesses a webservice to request data
result = self.driver.GetToolState(str(resource), str(self.site))
self.statedata_dic[i] = [result, state]
if result.Success:
print(str(resource) + result.ToolState.Description)
else:
print(str(resource) + 'no state av')
state_threads = []
# create a thread for every resource
for i in range(len(self.resources)):
s_t = threading.Thread(target=self.request_states, args=[self.resources[i], i])
# start thread
s_t.start()
state_threads.append(s_t)
for s_t in state_threads:
s_t.join()
self.resources是一个包含30个条目的列表。
启动线程时似乎出现了错误
我得到的是:
1备用
2备用
3备用
残疾的
5无
6待命
7待命
8备用
9无
10备用
11待命
12无
13待命
14待命
15无州av
16待命
17待命
18待命
19待命
当一个接一个地运行线程时,我想要什么/我得到什么(没有“no state av”,所有30个线程都提供响应):
1备用
残疾的
3备用
4备用
5无
6无
7待命
8备用
9无
10备用
11待命
12待命
13待命
14待命
15待命
16待命
17待命
18待命
19待命
20备用
21待命
22待命
23待命
24待命
25待命
26待命
27待命
28富有成效
29待命
30Standby您的问题很可能是由Python的GIL引起的。虽然您希望线程只会并行化您的请求,但实际上是介于两者之间的,并且是特定于Python的 根据“GIL会导致I/O绑定的线程提前调度到CPU绑定的线程之前,并阻止信号传递。” 如果仍要这样做,可以在线程内添加一个带有回退机制的重试:
import time
def request_states(self, resource, i):
# self.driver.GetToolState is a specific method defined in a dll
# it accesses a webservice to request data
backoff = 3
while backoff:
result = self.driver.GetToolState(str(resource), str(self.site))
if result.Success:
backoff = 0
self.statedata_dic[i] = [result, state]
print(str(resource) + result.ToolState.Description)
break
else:
print(str(resource) + 'no state av')
backoff -= 1
# increase time wait with every backoff decrement
# so that I increase the chances to receive a correct response
time.sleep(0.1 * (5 - backoff))
非常感谢,这解决了所有线程返回错误数据的问题!然而,我仍然有一个问题,一些线程甚至没有达到那个点,我启动30个线程,只得到15到20个响应。。。我将尝试在线程创建中实现类似的功能,也许这样可以。您应该确保driver.GetToolState是线程安全的。确保它不会锁定某些资源。也许你也应该有一个超时,如果需要的时间太长,就杀死线程,然后重新启动那些没有响应的线程。一些关于Python线程和GIL的好文章: