如何在python中同时调用一个脚本并运行另一个脚本?

时间:2016-10-13 04:07:43

标签: python concurrency subprocess

我想要完成的是从Twitter推送推文一小时,将推文列表写入文件,在最近一小时的推文中清理并运行分析,然后无限期地重复该过程。

我遇到的问题是,如果我在同一个处理流媒体的脚本中运行清理和分析推文 - 通过硬编码或从模块导入功能 - 整个脚本等待,直到这些过程完成,然后再次开始流式传输。有没有办法在流式脚本中调用清理和分析模块,以便它们同时运行,并且在清理和分析发生时流式传输不会停止?

我尝试使用subprocess.call('python cleaner.py', shell=True)subprocess.Popen('python cleaner.py', shell=True)来实现这一目标,但我并不是真的知道如何正确使用这些工具,上面的两个例子导致了流式传输停止,cleaner.py正在运行,然后流式传输恢复。

1 个答案:

答案 0 :(得分:1)

子过程

您可以尝试使用subprocess.Popen同时运行不同的脚本:

the_other_process = subprocess.Popen(['python', 'cleaner.py'])

这条线就能满足您的需求。您不希望做的是:

the_other_process.communicate()
# or
the_other_process.wait()

那些会阻止当前进程并等待另一个进程完成。在其他情况下非常有用的功能。

如果您想知道子进程是否已完成(但不等待它):

result = the_other_process.poll()
if result is not None:
    print('the other process has finished and retuned %s' % result)

使用线程也可以实现并发。在这种情况下,您没有运行新进程,只是将当前进程拆分为并发部分。试试这个:

def function_to_be_executed_concurrently():
    for i in range(5):
        time.sleep(1)
        print('running in separate thread', i)

thread = threading.Thread(target=function_to_be_executed_concurrently)
thread.start()

for i in range(5):
    time.sleep(1)
    print('running in main thread', i)

以上代码的结果应为running in separate threadrunning in main thread的混合输出。

线程与进程

  • 使用subprocess,您可以运行任何可以从shell独立运行的东西。它不一定是python。
  • 使用threading,您可以在并发执行线程中运行任何函数。
  • 线程共享相同的内存,因此很容易在它们之间共享数据(尽管在需要同步时存在问题)。使用流程,共享数据可能会成为一个问题。如果必须共享大量数据,则susbprocesses会慢得多。
  • 启动新进程比运行线程更慢并且消耗更多资源
  • 由于线程在同一进程中运行,因此它们共享绑定到相同的GIL,这意味着大多数事情将在同一个CPU核心上运行。如果需要加快非常慢的CPU消耗任务,在单独的进程中运行它们会更快。

多处理

multiprocessing模块提供类似于threading的接口,但它运行子进程。当您需要充分利用所有CPU核心时,这非常有用。

**请注意,subprocess.Popen(['python', 'cleaner.py'])subprocess.Popen('python cleaner.py', shell=True)相同,但前者是更好的学习方法。

例如,如果路径中有空格,则会失败:

subprocess.Popen('python My Documents\\cleaner.py', shell=True)

它失败了,因为它将MyDocuments\cleaner.py解释为两个单独的参数。

另一方面,这将按预期工作:

subprocess.Popen(['python', 'My Documents\\cleaner.py'])

它有效,因为参数是使用列表明确分开的。

如果其中一个参数位于变量中,后者尤其优越:

subprocess.Popen(['python', path_to_file])