Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 同时从多个线程调用.net库中的方法时,结果不完整_Python_Multithreading - Fatal编程技术网

Python 同时从多个线程调用.net库中的方法时,结果不完整

Python 同时从多个线程调用.net库中的方法时,结果不完整,python,multithreading,Python,Multithreading,我正在开发一个GUI,它显示我们工厂中某些工具的状态。可以通过集成到.dll文件中的webservice请求状态。启动GUI应用程序时,我希望同时请求所有工具的状态。为此,我为每个工具创建一个线程,然后调用一个方法来获取工具的状态。我得到了一些正确的响应,但大约一半的线程根本不提供响应,有些线程返回错误的值 如果我一个接一个地运行请求,一切都会很好。但这需要很长时间 def request_states(self, resource, i): # self.driver.GetToolS

我正在开发一个GUI,它显示我们工厂中某些工具的状态。可以通过集成到.dll文件中的webservice请求状态。启动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备用 残疾的 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的好文章: