我正在使用一个GUI来显示工厂中某些工具的状态。可以通过集成到.dll文件中的Web服务来请求状态。当我的GUI应用程序启动时,我想同时请求所有工具的状态。为此,我为每个工具创建一个线程,然后调用一个应该获取工具状态的方法。我得到了一些正确的响应,但是大约有一半的线程根本不提供响应,有些返回了错误的值。
如果我一个接一个地运行请求,那么一切都很好。但这花了太长时间。
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待机 4已禁用 5无 6待机 7待机 8待机 9无 10待机 11待机 12无 13待机 14待机 15无状态AV 16待机 17待机 18待机 19待机
我想要什么/一个接一个地运行线程时得到什么(没有“ no state av”,所有30个线程都提供响应):
1待机 2已禁用 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待机 30待机
答案 0 :(得分:0)
您的问题很可能是由Python的GIL引起的。尽管您期望线程只会并行化您的请求,但实际上介于两者之间,并且特定于Python。
根据Python's wiki,“ 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))