Saqib Ali
Saqib Ali

Reputation: 12585

Why won't this Python child-thread allow the Parent thread to do its work?

I have the following python multi-threading program

#!/usr/bin/env python
from multiprocessing import Process
import time


child_started = False

def child_func():
    global child_started
    child_started = True
    print "Child Started"
    while True:
        time.sleep(1)
        print "X"


if __name__ == '__main__':
    global child_started
    child_thread = Process(target=child_func)
    child_thread.start()
    while child_started is False:
        time.sleep(2)
    print "Parent Starting Process"

    # Do something

    print "Parent Done"
    child_thread.terminate()
    print "Child Cancelled by Parent"
    child_thread.join()

I expected the child process to do some work, but then eventually the parent thread to come in and terminate it. However that's not happening. Why? As you can see below, once the child process starts running, the Parent process gets frozen out and never does anything. Why?? How to fix.

$ ~/threads.py
~/threads.py:20: SyntaxWarning: name 'child_started' is assigned to before global declaration
Child Started
X
X
X
X
X  

Upvotes: 0

Views: 825

Answers (2)

Haifeng Zhang
Haifeng Zhang

Reputation: 31895

As @thepaul said, your child_started variable is local variable and it is not shared between multiprocessing communications.

I suggest your create a Queue, once the child process get started, put an element into the queue and checks the queue.empty() in your main process and do your work.

#!/usr/bin/env python
from multiprocessing import Process
from multiprocessing import Queue
import time



def child_func(queue):

    print "Child Started"
    # put anything into queue after `child_func` get invoked, indicates
    # your child process is working
    queue.put("started...")  
    while True:
        time.sleep(1)
        print "X"


if __name__ == '__main__':

    queue = Queue()
    child_thread = Process(target=child_func,args=(queue,))
    child_thread.start()

    # stop sleeping until queue is not empty
    while queue.empty():
        time.sleep(2)
    print "Parent Starting Process"

    # Do something

    print "Parent Done"
    child_thread.terminate()
    print "Child Cancelled by Parent"
    child_thread.join()

Upvotes: 1

the paul
the paul

Reputation: 9161

When you set child_started in your child_func function, you are setting a local variable, and not the global module-level one. Also, since you are using multiprocessing, the two processes won't even share the global variable either.

You should pass something with shared storage across the participating proceses, such as multiprocessing.Event, instead.

edit: whoops, I answered this first as if you were using threading instead of multiprocessing.

Upvotes: 0

Related Questions