can't delete from a dictionary in a loop

George Sakkis george.sakkis at gmail.com
Sat May 17 04:06:12 EDT 2008


On May 16, 5:22 pm, "Dan Upton" <up... at virginia.edu> wrote:
> This might be more information than necessary, but it's the best way I
> can think of to describe the question without being too vague.
>
> The task:
>
> I have a list of processes (well, strings to execute said processes)
> and I want to, roughly, keep some number N running at a time.  If one
> terminates, I want to start the next one in the list, or otherwise,
> just wait.
>
> The attempted solution:
>
> Using subprocess, I Popen the next executable in the list, and store
> it in a dictionary, with keyed on the pid:
> (outside the loop)
> procs_dict={}
>
> (inside a while loop)
> process = Popen(benchmark_exstring[num_started], shell=true)
> procs_dict[process.pid]=process
>
> Then I sleep for a while, then loop through the dictionary to see
> what's terminated.  For each one that has terminated, I decrement a
> counter so I know how many to start next time, and then try to remove
> the record from the dictionary (since there's no reason to keep
> polling it since I know it's terminated).  Roughly:
>
> for pid in procs_dict:
>   if procs_dict[pid].poll() != None
>    # do the counter updates
>    del procs_dict[pid]

Since you don't look up processes by pid, you don't need a dictionary
here. A cleaner and efficient solution is use a deque to pop processes
from one end and push them to the other if still alive, something like
this:

from collections import deque

processes = deque()
# start processes and put them in the queue

while processes:
    for i in xrange(len(processes)):
        p = processes.pop()
        if p.poll() is None: # not finished yet
            processes.append_left(p)
    time.sleep(5)


HTH,
George



More information about the Python-list mailing list