0

I don't know if what I intend to do is even possible or reasonable, so I'm open for any suggestions.

Currently I have a script which starts n subprocesses of some.exe id which I regularly poll() to determine if they terminated and if so, with which errorlevel. The subprocesses are saved in a dict (key = subprocess, value = id). n instances of some.exe are kept running, each with an own id, until every id of a predefined list has been processed.

some.exe has no gui on it's onw, it writes the progress to the stdout, which I do not need. Now, for some reason sometimes, some.exe doesn't continue, as if it would wait - thus poll() never produces an errorlevel and done = proc.poll() is not None is never true. Which sooner or later leads to my dict of n procs, all being inactive and the overall progress is stuck.

If issued manually in a cmd, some.exe with an id, that shows this behaviour in the script - works perfectly fine.

Therefore my idea was to start a new cmd window from the script, which runs some.exe with the id, but I should still be able to poll() said exe.

Here's roughly what I have so far:

while id_list > 0:
    if len(proc_dict) < n:
        id = next_id()
        proc = subprocess.Popen(["some.exe", id], stdout=PIPE)
        proc.poll()
        proc_dict[proc] = id
    else:
        done_procs = []
        for proc in proc_dict.keys():
            done = proc.poll() is not None

            if done:
                print("returncode: "+proc.returncode)
                done_procs.append(proc)

        if done_procs:
            for p in done_procs:
                del proc_dict[p]

        time.sleep(2)

edit: if I proc.communicate()[0] in the else: where the sleep is located, some.exe is able to continue/finish, but as communicate waits for the process, it slows down the script way too much.

Daedalus Mythos
  • 565
  • 2
  • 8
  • 24

1 Answers1

2

I believe the problem is that some.exe's output is enough to fill the os pipe buffer, causing a deadlock. There is a warning about this in the docs here

If you want to discard the stdout, instead of sending it to a pipe you could instead send it to devnull, this post explains how to do that

Community
  • 1
  • 1
GP89
  • 6,600
  • 4
  • 36
  • 64