2
\$\begingroup\$

I have a class called _NodeProcess. It consists of a mainloop (main function) which is run in a separate process and methods (start and stop) that control the mainloop. Here's the code:

class _NodeProcess:
 def __init__(self, master):
 self.master = master
 self.process = multiprocessing.Process(target=self.main)
 self.is_alive = True
 self.is_dead = False
 def start(self):
 self.process.start()
 def stop(self):
 self.is_alive = False
 while not self.is_dead:
 pass
 def main(self):
 while self.is_alive:
 task = self.master.give_task()
 self.master.grab_result({'header': 'result', 'result': self.master.function(task), 'task': task})
 self.is_dead = True

The part that worries me is the stop function. On each mainloop iteration, I check whether I should continue (self.is_alive == True), and if I shouldn't, I stop and do self.is_dead = True to confirm that i had quit the loop. Meanwile, in the stop function, after setiing self.is_alive to False, and block until self.is_dead == True.

My concern is the way in which I block:

while not self.is_dead:
 pass

I'm afraid it may eat to much resources just iterating over that loop at a very high speed. So, I considered another option, using time.sleep:

import time
while not self.is_dead:
 time.sleep(1)

But it doesn't seem like a best way to block until some condition is met (I need an extra library; I lose 0.5 seconds on average when I call the stop method, if I make the period less, I spend more resources, so it's some kind of a compromise, which has to be made each time I write code like that). Is there a better solution for this particular problem, or maybe it's better to redesign the class in some way that would allow not facing this problem at all?

asked Oct 28, 2015 at 0:20
\$\endgroup\$
2
  • 2
    \$\begingroup\$ You need real synchronization. Look at multiprocessing.Lock and/or multiprocessing.Condition. Playing with time.sleep() is an anti-pattern. \$\endgroup\$ Commented Oct 28, 2015 at 0:39
  • 1
    \$\begingroup\$ I realized that I can just call self.process.join() and to me it seems the best solution in this particular situation (waiting for thread to finish), though, thank you for your adivice, now I see I need to learn more about thread synchronization, because in a common situation when I need to wait for some other thing to happen, I'll need it. Thanks:) \$\endgroup\$ Commented Oct 28, 2015 at 1:22

2 Answers 2

2
\$\begingroup\$

You don't need a self.is_dead. You simply need to block until the thread is complete. For that, we have join():

def stop(self):
 self.is_alive = False
 self.process.join()
answered Oct 28, 2015 at 11:17
\$\endgroup\$
0
\$\begingroup\$

I must preface with the fact that I know little about multiprocessing. However, I do know that for a while loop of that format using time, it doesn't particularly matter what you set it to.

On my system, the code:

While 1:
 time.sleep(.1)

still uses an undetectable (0.0%) amount of CPU, in comparison with time.sleep(1). Even time.sleep(.01) only uses .4% of my CPU. There are likely better solutions that have to do specifically with that library, but this is likely the simplest.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
answered Oct 28, 2015 at 4:12
\$\endgroup\$
1
  • \$\begingroup\$ Yes, it does use a little cpu, and really works, but the problem that bothered me was that I have to choose the time. And I have no idea how to choose between 0.1 and 0.01 for example, so, when I finally write some number in there, I can't be sure I chose the right one. That doesn't feel as a good programming practice:) And also, I have to import an extra library, which is also not so great. \$\endgroup\$ Commented Oct 28, 2015 at 13:45

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.