【问题标题】:Problem with calling WINDOWS cmd.exe by using subprocess module: fail to control parallel process limitation使用子进程模块调用WINDOWS cmd.exe的问题:无法控制并行进程限制
【发布时间】:2020-01-11 03:44:50
【问题描述】:

我现在正在研究 Python,编写代码需要调用 WINDOWS cmd.exesubprocess

我想连续运行数千个进程,但同时运行的进程只有 6 个或更少。

文章Control the number of subprocesses using to call external commands in python 提供了解决方案,它在调用远程桌面之类的程序时似乎工作正常,关闭后会出现一个新程序。但是当我在调用cmd.exe 时应用这些代码时遇到了问题。代码如下:

import subprocess
from multiprocessing.pool import ThreadPool as Pool

def worker(cmd): 
    p = subprocess.Popen(cmd, );
    p.wait()

commands = ['C:\Windows\System32\mstsc.exe',
            'C:\Windows\System32\mstsc.exe',
            'C:\Windows\System32\mstsc.exe',
            'C:\Windows\System32\mstsc.exe',
            'C:\Windows\System32\mstsc.exe',]

pool = Pool( processes = 2 );
results =[pool.apply_async(worker, [cmd]) for cmd in commands];
ans = [res.get() for res in results];
This works fine. A new window shows when  one another closed.

这段代码运行良好。

但是如果进程是 cmd.exe

import subprocess
from multiprocessing.pool import ThreadPool as Pool

def worker(cmd): 
    p = subprocess.Popen(cmd, );
    p.wait()

commands = ['cmd.exe /c start "Test1" /d E:\pyworkspace\FAST\ FAST_RV_W64.exe 334.in',
            'cmd.exe /c start "Test2" /d E:\pyworkspace\FAST\ FAST_RV_W64.exe 893.in',
            'cmd.exe /c start "Test3" /d E:\pyworkspace\FAST\ FAST_RV_W64.exe 9527.in',
            'cmd.exe /c start "Test4" /d E:\pyworkspace\FAST\ FAST_RV_W64.exe 114514.in',
            'cmd.exe /c start "Test5" /d E:\pyworkspace\FAST\ FAST_RV_W64.exe 1919810.in']

pool = Pool( processes = 2 );
results =[pool.apply_async(worker, [cmd]) for cmd in commands];
ans = [res.get() for res in results];

*FAST_RV_64.exe 是我的工具程序之一,*.in 是设置文件。 调用cmd.exe,所有cmd窗口同时跳出,限制无效。

import subprocess
from multiprocessing.pool import ThreadPool as Pool

def worker(cmd): 
    p = subprocess.Popen(cmd, );
    p.wait()

commands = ['cmd.exe /c start "Test1" mstsc.exe',
            'cmd.exe /c start "Test2" mspaint.exe',
            'cmd.exe /c start "Test3" SnippingTool.exe',
            'cmd.exe /c start "Test4" mstsc.exe',
            'cmd.exe /c start "Test5" mspaint.exe']

pool = Pool( processes = 2 );
results =[pool.apply_async(worker, [cmd]) for cmd in commands];
ans = [res.get() for res in results];

如果我通过cmd.exe调用程序,它也会一起跳出来。

我也尝试了上面文章中的其他方法,但没有一个有效。

我想知道为什么会发生这种情况以及如何修复我的代码。

【问题讨论】:

  • 你为什么要通过cmd.exe而不是直接运行?
  • @sam-mason 运行 cmd.exe 显示与直接运行 FAST_RV_64.exe 相同的结果。 cmd.exeFAST_RV_64.exe 执行后自动启动。

标签: python cmd subprocess


【解决方案1】:

apply_async() 的用法看起来有点可疑 - 改为 imap_unordered() 怎么样?

另外,cmd + start 不一定要等待子命令退出,所以这也可能是您的问题的一部分。

这样的事情怎么样?

import subprocess
from multiprocessing.pool import ThreadPool as Pool


def worker(file):
    p = subprocess.Popen(
        [r"E:\pyworkspace\FAST\FAST_RV_W64.exe", file],
        cwd=r"E:\pyworkspace\FAST",
    )
    p.wait()


files = [
    "334.in",
    "893.in",
    "9527.in",
    "114514.in",
    "1919810.in",
]

with Pool(processes=2) as pool:
    for result in pool.imap_unordered(worker, files):
        pass

【讨论】:

  • 我的问题可以用这段代码解决。但我想知道有没有什么办法可以让每个进程在单独的窗口中工作?
  • 这真的取决于 FAST_RV_W64 对其控制台或窗口的作用。
【解决方案2】:

根据您所说,这里不需要运行cmdstart 程序。只需从命令行中删除它们,它们不会做任何事情。

当只需要一个(您的程序)时,您不必要地运行了两个额外的程序(cmdstart

如果你真的想让你的电脑做这些额外的工作,你可以将/wait 标志传递给startdocs 将其描述为:

启动一个应用程序并等待它结束。

但是,鉴于您在问题中所写的内容,您最好直接运行您的程序

【讨论】:

  • 抱歉没有表达清楚,我想说的是申请cmd.exe可能是必要的,因为工具程序是一种带有CLI的程序,它打开了一个cmd.exe对启动后开始运行代码。所以如果我能解决“cmd.exe一起启动问题”,也许我可以用这个工具解决我的问题。
猜你喜欢
  • 2012-05-01
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多