I have been trying to learn how multiprocessing works in python, and have created a very simple script to test my understanding.
Everything seems to work fine, except for the fact that, within a process, none of value assignments that happen after a while loop appear to be completed.
If I replace the while loop with a for loop, or remove it completely, everything seems to work as expected.
Here is the main.py:
from timepieces import Stopwatch
def run():
watch = Stopwatch()
watch.start()
can_count = 0 if (raw_input('Press q to stop and see seconds counted') == 'q') else 1
watch._can_count.value = can_count
print watch.get_seconds()
if __name__ == "__main__":
run()
And the timepieces.py file (contains class that creates and controls process):
from multiprocessing import Process, Value
import time
import math
class Stopwatch:
_count_val = None
_proc = None
_can_count = None
def count_seconds(self, can_count, count_val):
seconds = 0
count_val.value = 23
#print can_count.value == 1
while can_count.value == 1:
seconds += 1
count_val.value = seconds
def start(self):
self._count_val = Value('i', 0)
self._can_count = Value('i', 1)
self._proc = Process(target = self.count_seconds, args = (self._can_count, self._count_val))
self._proc.start()
def get_seconds(self):
return self._count_val.value
Any thoughts are appreciated.
You need to join the child process when your finished with it. Here's a cleaner example of what your trying to achieve. Notice how all of the stuff related to the process is encapsulated out into one class? It makes dealing with threads and process much easier if you can interact with them through a clean interface.
Here's the main module
from asynctimer import AsyncTimer
import time
def run():
atimer = AsyncTimer()
atimer.start()
print 'initial count: ', atimer.get_seconds();
print 'Now we wait this process,'
print 'While the child process keeps counting'
time.sleep(3)
print '3 seconds later:', atimer.get_seconds();
atimer.stop()
if __name__ == '__main__':
run()
Here's the class that handles the child process.
from multiprocessing import Process, Value
class AsyncTimer():
def __init__(self):
self._proc = None
self._do_count = Value('b',True)
self._count = Value('i', 0)
def _count_seconds(self):
while self._do_count.value:
self._count.value += 1
def start(self):
self._proc = Process(target=self._count_seconds)
self._proc.start()
def stop(self):
self._do_count.value = False
self._proc.join()
def get_seconds(self):
return self._count.value