我目前在理解线程方面遇到了一些问题,或者可能在理解python中如何通过线程传递/分配变量方面遇到了一些问题。我有一个简单的程序,它接收屏幕上显示的当前股票列表,并获取与这些股票相关的股票信息。我使用线程,这样我可以不断更新屏幕,不断收集数据。我有两个问题:
dataCollector_thread()
内部,我理解如果我在stocksOnScreenListInfo
中追加变量(stocksOnScreenListInfo
),那么main
内部的变量(stocksOnScreenListInfo
)将被更新李>但是,我不想附加到列表中,而只是像下面那样重新分配列表,但这不起作用
def dataCollector_thread(stocksOnScreenListInfo, stocksOnScreen):
while(True):
placeholder = []
for stock in stocksOnScreen:
placeholer.append(RetrieveQuote(stock))
stocksOnScreenListInfo = placeholder
time.sleep(5)
在screenUpdate_thread
内,我想将stocksOnScreen
更新为函数UpdateScreen
定义的变量“TSLA”。这似乎没有更新它在main
中对应的stocksOnScreen
,因为当我打印检查时,它继续说“AAPL”
def main(args):
stocksOnScreen = ["AAPL"] # List of the stocks currently displayed on LED screen
stocksOnScreenListInfo = [] # The quote information list for each stock on screen
thread_data_collector = threading.Thread(target=dataCollector_thread, args=(stocksOnScreenListInfo,stocksOnScreen))
thread_data_collector.daemon = True
thread_data_collector.start()
thread_screen = threading.Thread(target=screenUpdate_thread, args=(stocksSearchArray,stocksOnScreen))
thread_screen.daemon = True
thread_screen.start()
def dataCollector_thread(stocksOnScreenListInfo, stocksOnScreen):
while(True):
for stock in stocksOnScreen:
stocksOnScreenListInfo.append(RetrieveQuote(stock))
time.sleep(5)
def screenUpdate_thread(stocksSearchArray, stocksOnScreen):
while(True):
stocksOnScreen = UpdateScreen(stocksSearchArray)
def UpdateScreen(stocksSearchArray):
pass
return ["TSLA"]
此功能有几个问题:
您正在将此函数中的
stocksOnScreenListInfo
分配给一个新列表placeholder
。您要做的是修改适当的内容,以便更新main
中的stocksOnScreenListInfo
。您可以这样做:stocksOnScreenListInfo[:] = placeholder
(这意味着使用新列表从头到尾更改内容)stocksOnScreen
在for循环中迭代时可能会更改,因为您正在另一个线程中更新它。你应该原子化地做这件事。A lock (您将其作为参数传递给函数)将在这里有所帮助:它是一个同步原语,设计用于在多个线程共享数据且其中至少一个线程修改数据时防止数据争用我看不到
stocksOnScreenListInfo
在代码中的其他任何地方被使用。它是否用于其他功能?如果是这样的话,你应该考虑在它周围加一把锁我将对函数进行如下修改:
在其他线程函数中:
您正在将
stocksOnScreen
分配给此函数中的新列表;它不会影响main
中的stocksOnScreen
。同样,您可以使用符号stocksOnScreen[:] = new_list
来实现这一点。我会在更新stocksOnScreen
之前锁定,以确保其他线程函数dataCollector_thread
以原子方式访问stocksOnScreen
,如下所示:正如你所看到的,我在一个小睡眠,否则的功能将不断循环,太CPU密集。另外,它将为Python提供一个在线程函数之间切换上下文的机会
最后,在
main
中创建一个锁:并将
lock
作为参数传递给这两个函数stocksOnScreen = ...
更改引用本身。由于引用作为参数传递给函数/线程,因此对函数/线程中原始引用的副本进行更改。(两个函数/线程都有自己的副本。)因此,您应该操作它所引用的列表对象(例如
list.clear()
和list.extend()
)但是,正如您所看到的,它现在不再是一个原子操作。所以有可能
dataCollector_thread
会在一个空列表上工作(即什么都不做)并睡眠5秒钟。我也在下面提供了一个可能的解决方法。但不确定它是否应该(完美地)工作:注意:根据this answer,python列表是线程安全的,因此复制解决方案应该起作用
您可能也可以使用^{} 而不是将
stocksOnScreen
作为参数传递:参考文献:https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python
这里有三个选项,因为类似python的java通过值传递参数&;不是参考资料
首先,使用全局参数
第二,更新程序函数
第三,公开全局参数持有者
我希望这回答了你的问题;)
相关问题 更多 >
编程相关推荐