我正在尝试同时运行多个功能:
-或所谓的函数,因为它们属于一个类:
from sh import tail
data = {}
class my_Class():
def __init__(self):
"""Nothing to declare for initializing"""
def get_data(self, filepath):
"""I'm trying to import the data from several files"""
for line in tail("-f", "-n 1", filepath, _iter=True):
data[filepath] = line
print(data)
my_Class().get_data("path/to/file") #call 1
my_Class().get_data("path/to/another/file") #call 2
# ... 14 similar calls
我希望每个调用都将其数据附加到字典中。因此,当我打电话时:
my_Class().get_data("path/to/file") #call 1
my_Class().get_data("path/to/another/file") #call 2
# ... 14 similar calls
结果应打印:
#1 {'filepath1' : line}
#2 {'filepath1' : line, 'filepath2' : line}
#3 {'filepath1' : line, 'filepath2' : line, 'filepath3' : line}
# ... 13 more
同时,我希望字典数据的内容{...}保持动态变化;因为文件中的数据很灵活。例如:
#1 {'filepath1' : line}
#2 {'filepath1' : last_line_in_the_file}, 'filepath2' : line}
#3 {'filepath1' : last_line_in_the_file, 'filepath2' : last_line_in_the_file, 'filepath3' : line}
# ... 13 more
我已经检查了这些帖子:但是它没有按照我的要求进行; Python: How can I run python functions in parallel?,How to do parallel programming in Python 谢谢!请告诉我是否听起来有些晦涩
答案 0 :(得分:0)
听起来您在这里要求两件事:
对于第一个,您猜到了答案是线程。对于某些程序,这不是答案,因为他们花费大量时间在Python中进行大量的CPU计算,或者因为您需要成千上万的任务而不是少数几个。但是在这里,只需将每个线程作为线程运行即可。
代替此:
my_Class().get_data("path/to/file") #call 1
my_Class().get_data("path/to/another/file") #call 2
…您创建线程:
t1 = threading.Thread(target=my_Class().get_data, args=
(“路径/至/文件”,)) t2 = threading.Thread(target = my_Class()。get_data,args = (“路径/到/另一个/文件”,))
…然后启动它们:
t1.start()
t2.start()
…然后等待它们全部完成(在这种情况下,这显然将永远存在,因此您可以在此处简化事情……):
t1.join()
t2.join()
现在,如何在线程之间共享可变数据?
首先,您可以从不同的线程访问和变异相同的值。但总的来说,除非您不知道不需要一个值,否则就希望对每个值进行锁定。
如果您只关心Windows,macOS,Linux和BSD上的CPython,那么将具有字符串键的字符串值插入dict对象是不需要锁的事情之一。 print
到stdout
是另一个。而这些是您共享的唯一内容。因此,您实际上不需要在这里锁。一切都会起作用。
但是,由于您可能不知道dict以这种方式是安全的,所以让我们看看如何使用锁。
data = {}
data_lock = threading.Lock()
# etc.
def get_data(self, filepath):
"""I'm trying to import the data from several files"""
for line in tail("-f", "-n 1", filepath, _iter=True):
with data_lock:
data[filepath] = line
print(data)
仅此而已。
事情会变得更加复杂。例如,您实际上不需要在这里呆多长时间。如果您有30个线程,则很有可能其中一个正在尝试抓住该锁以添加新值,而另一个线程已经从data
中创建了一个字符串,并花了时间打印该字符串(打印到stdout
的速度很慢),但是尚未释放锁定。如果是这样,您可以通过分解来获得更多的并行性:
def get_data(self, filepath):
"""I'm trying to import the data from several files"""
for line in tail("-f", "-n 1", filepath, _iter=True):
with data_lock:
data[filepath] = line
with data_lock:
datastr = str(data)
print(datastr)
但这真的很复杂。关于线程的困难部分是当您必须编写单独的锁时,因为您有在线程之间传递的单独数据,依此类推。对于这样的简单情况,实际上非常简单。