Question

I'm having trouble getting rid of some zombie processes. I've read some of the other answers to this problem and from what I gather is this occurs when your child processes do not close correctly. I wasn't having this problem until I added a while loop to my code. Take a look.

def worker(self):
    cmd = ["/home/orlando/CountMem","400000000","2000"]
    p = subprocess.Popen(cmd,stdout=subprocess.PIPE)
    id_list = []
    id_list.append(p.pid)



    while len(id_list) > 0:
         for num in id_list:
             stat_file = open("/proc/{0}/status".format(num))
             mem_dict = {}
             for i, line in enumerate(stat_file):
                 if i == 3:
                    #print line
                     mem_dict['ID'] = line
                     print(mem_dict)
                 if i == 10:
                    #print line
                     mem_dict['Mem'] = line
                     print(mem_dict)

    return id_list

if __name__ == '__main__':
    count = multiprocessing.cpu_count()
    pool = multiprocessing.Pool(processes = count)
    print(pool.map(worker,['ls']*count))

my code loops through the "/proc/PID/status" of each child process multiple times grabbing information. Without the "while" loop it doesn't spawn zombie processes but it also doesn't fulfill what I want it to do. With the loop it fulfills what I want it to do but it also spawns zombie processes. My question is how do I keep my code from spawning zombies. Below is some of the output I get:

{'ID': 'Pid:\t2446\n'}                                                                                              
{'ID': 'Pid:\t2441\n'}                                                                                              
{'Mem': 'VmPeak:\t  936824 kB\n', 'ID': 'Pid:\t2446\n'}                                                             
{'Mem': 'VmPeak:\t  542360 kB\n', 'ID': 'Pid:\t2441\n'}                                                             
{'ID': 'Pid:\t2442\n'}                                                                                              
{'Mem': 'VmPeak:\t 1037580 kB\n', 'ID': 

this continues until the child processes are complete then it immediately begins printing this:

{'ID': 'Pid:\t2602\n'}                                                                                              
{'ID': 'Pid:\t2607\n'}                                                                                              
{'ID': 'Pid:\t2606\n'}                                                                                              
{'ID': 'Pid:\t2604\n'}                                                                                              
{'ID': 'Pid:\t2605\n'}                                                                                              
{'Mem': 'Threads:\t1\n', 'ID': 'Pid:\t2606\n'}                                                                      
{'Mem': 'Threads:\t1\n', 'ID': 'Pid:\t2607\n'}                                                                      
{'Mem': 'Threads:\t1\n', 'ID': 'Pid:\t2605\n'}                                                                      
{'Mem': 'Threads:\t1\n', 'ID': 'Pid:\t2604\n'} 

Can anyone help me understand and solve what is happening?

Was it helpful?

Solution

I figured out the answer I needed to add p.poll() I added it inside the while loop.

def worker(self):
    cmd = ["/home/orlando/CountMem","400000000","2000"]
    p = subprocess.Popen(cmd,stdout=subprocess.PIPE)
    id_list = []
    id_list.append(p.pid)



    while len(id_list) > 0:
         for num in id_list:
             stat_file = open("/proc/{0}/status".format(num))
             mem_dict = {}
             for i, line in enumerate(stat_file):
                 if i == 3:
                    #print line
                     mem_dict['ID'] = line
                     print(mem_dict)
                 if i == 10:
                    #print line
                     mem_dict['Mem'] = line
                     print(mem_dict)
         p.poll()
    return id_list

if __name__ == '__main__':
    count = multiprocessing.cpu_count()
    pool = multiprocessing.Pool(processes = count)
    print(pool.map(worker,['ls']*count))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top