同时运行Python脚本?

3
需要同时运行两个Python3脚本。第一个脚本(app1.py)向第二个脚本(app2.py)提供信息。两个脚本需要同时运行,最好从单个脚本中运行。
脚本1是基于bs4的爬取脚本,无限循环运行而不会结束。脚本2是一个FLask Web应用程序,显示来自脚本1的信息。是否可以运行脚本1而不导入它,因为这会导致由脚本1无限循环运行引起的问题?
我如何从单个脚本中同时运行两个脚本?

1
请参阅multiprocessing - Peter Wood
会看一下。 - arthem
1个回答

3

设计

首先,在增加复杂性之前(特别是涉及并发编程),您应该问自己,我真的需要这样做吗?Flask应用程序是否可以在请求时触发新的抓取?

并发性

在Python中需要同时运行任务时,有三种主要方法:

  1. 多线程
  2. 多进程
  3. asyncio

进程在操作系统方面是不同的东西,并包含线程。asyncio是另一种思考这个问题的方式,它允许您忘记操作系统。

Python有一个名为全局解释器锁的特性,这基本上意味着它一次只能在一个进程中解释一行字节码。这意味着如果您的应用程序使用多线程,则一个线程将冻结,而另一个线程将执行其他任务。需要注意的是,此限制仅适用于解释字节码,如果有像flask服务器这样的IO密集型工作,那么当服务器忙于处理任务时,您可能会发现仍有足够的时间可以使用多线程

为什么要选择多进程

很多工作已经投入到使多线程多进程之间的接口非常相似,因此它增加了非常少的复杂性,并且为了确保您不会阻塞您的服务器,最好只使用多进程

为什么要选择多线程

multiprocessing 的缺点在于 Python 必须在进程之间pickle数据,因为它们不能像线程一样共享内存。与 multithreading 相比,这种方法较慢,但对于合理数量的数据仍然非常快。记住,“过早优化是万恶之源”,在进行优化之前和之后profile你的代码,以决定是否值得。

为什么选择 asyncio

asyncio是为了“使编写显式异步、并发的Python代码更加容易和Pythonic”而添加到Python中的,有些人可能不同意。我认为最好尝试一下,看看它是否适合您的需求。从您的应用程序声音来看,它不够大,无法从asyncio允许的大规模并发中受益。

个人而言,我会选择multiprocessing来处理这种情况。

导入

通常不希望import my_script_which_loops永远挂起,而是经常会看到以下内容:

# my_script_which_loops

def main():
    while True:
        print("I am scraping the thing!")

if __name__ == "__main__":
    main()


这意味着如果您运行\> python my_script_which_loops.py,则会按预期方式抓取内容,但是如果该脚本不是主要脚本,则导入它不会挂起。有关更多信息,请参见此处

不错的写作。我的问题是它一直卡住。目前使用命令[os.system('python3 scraper.py')],但我怀疑这不是最好的方法。另外,你能否澄清“但如果脚本不是主要脚本,则导入它不会卡住”? - arthem
1
提供的链接提供了很深入的内容,但只是一个概述。__name__是一个特殊变量,它根据文件所在的位置而设置为不同的值。如果你运行的是有import yx.py,那么在x.py中,__name__被设置为"__main__"。在y.py中,__name__y。我花了一点时间才理解清楚这个概念。 - Edwin Shepherd
1
你说得对,os.system 不是最好的方法,请查看链接文档中的一些示例,如果我有时间,我可能会编辑答案并提出建议的方法。 - Edwin Shepherd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接