我写了一个脚本,从我学校的网站上提取数据,而且我在执行时遇到了一些麻烦。
有20多个校区,每个校区都有三个学期的数据。该脚本查找这些学校名称,然后是每个学校可用的学期,然后是每个学期提供课程的科目/部门。然后脚本搜索每个部门的类,然后我用这些数据做事。
我在一个校园里定时执行脚本,它跑了三分多钟。当我为所有24个校区运行它花了一个多小时。我正在使用"请求"库,同步运行每个HTTP请求。我正在使用"请求"库,主要是因为它很好地处理会话。
通过让每个学期的各种请求并行运行,我正在寻找降低脚本运行时间的方法。我怀疑,如果我异步运行三个学期,那么每个学校应该花一分钟而不是三分钟。然后,我可以并行运行所有学校,并为所有数据实现相同的分钟。一分钟不到一个小时四分之一!
我猜错了,多线程/处理会大大缩短执行时间吗?我应该为线程或进程使用哪些Python库?
一旦我在一个主题上处理了每所学校,我该如何将所有学校的数据合并到一个地方?我知道线程改变全球状态的做法很糟糕,但这里的替代方案是什么?
答案 0 :(得分:0)
1)你没错。对线程使用threading
库。对于流程,您可以使用multiprocessing
或os.fork
或subprocess
,具体取决于您希望如何使用它们。
2)谁说改变全球国家是一种糟糕的做法?这总是取决于背景。显然,你必须以某种方式在线程之间共享数据结构。但是,您不必使用全局变量。例如:
from threading import Thread
def my_task(id, holder, some_other_args):
# do something
holder[id] = my_result
def main():
total_data = {}
threads = []
for i in range(100):
t = Thread(target=my_task, args=(i, total_data, ...))
t.start()
threads.append(t)
for t in threads:
t.join()
print total_data # <-- you have all results here
if __name__ == "__main__":
main()
答案 1 :(得分:0)
在python中,你想要多线程多处理。由于GIL,线程在Python中表现不佳。
答案 2 :(得分:0)
为什么要使用全局变量?与奇特相同的代码,但没有传递给线程的全局变量:
#!/usr/bin/python3
import threading
class MyThread(threading.Thread):
def __init__(self, target, name=None, args=(), kwargs={}):
super().__init__(target=target, name=name, args=args, kwargs=kwargs)
self.output = None
def run(self):
self.output = self._target(*self._args, **self._kwargs)
def my_task(i):
# do something
return 'response ' + str(i)
def main():
total_data = list()
threads = []
for i in range(5):
t = MyThread(target=my_task, args=[i,])
t.start()
threads.append(t)
for t in threads:
t.join()
total_data.append(t.output)
print(total_data)
if __name__ == "__main__":
main()
输出是:
Jean@MyDesktop:~$ ./test_threads.py
['response 0', 'response 1', 'response 2', 'response 3', 'response 4']
@yorodm:在这种情况下,我认为多线程应该足够了,除非在数据上进行繁重的处理。