简体   繁体   中英

Python simplest form of multiprocessing

Ive been trying to read up on threading and multiprocessing but all the examples are to intricate and advanced for my level of python/programming knowlegde. I want to run a function, which consists of a while loop, and while that loop runs I want to continue with the program and eventually change the condition for the while-loop and end that process. This is the code:

class Example():

    def __init__(self):
        self.condition = False

    def func1(self):
        self.condition = True
        while self.condition:
            print "Still looping"
            time.sleep(1)
        print "Finished loop"

    def end_loop(self):
        self.condition = False

The I make the following function-calls:

ex = Example()
ex.func1()
time.sleep(5)
ex.end_loop()

What I want is for the func1 to run for 5s before the end_loop() is called and changes the condition and ends the loop and thus also the function. Ie I want one process to start and "go" into func1 and at the same time I want time.sleep(5) to be called, so the processes "split" when arriving at func1 , one process entering the function while the other continues down the program and start with the time.sleep(5) execution.

This must be the most basic example of a multiprocess, still Ive had trouble finding a simple way to do it!

Thank you

EDIT1: regarding do_something . In my real problem do_something is replaced by some code that communicates with another program via a socket and receives packages with coordinates every 0.02s and stores them in membervariables of the class. I want this constant updating of the coordinates to start and then be able to to read the coordinates via other functions at the same time.

However that is not so relevant. What if do_something is replaced by:

time.sleep(1)
print "Still looping"

How do I solve my problem then?

EDIT2: I have tried multiprocessing like this:

from multiprocessing import Process
ex = Example()    
p1 = Process(target=ex.func1())
p2 = Process(target=ex.end_loop())

p1.start()
time.sleep(5)
p2.start()

When I ran this, I never got to p2.start() , so that did not help. Even if it had this is not really what Im looking for either. What I want would be just to start the process p1 , and then continue with time.sleep and ex.end_loop()

The first problem with your code are the calls

p1 = Process(target=ex.func1())
p2 = Process(target=ex.end_loop())

With ex.func1() you're calling the function and pass the return value as target parameter. Since the function doesn't return anything, you're effectively calling

p1 = Process(target=None)
p2 = Process(target=None)

which makes, of course, no sense.

After fixing that, the next problem will be shared data : when using the multiprocessing package, you implement concurrency using multiple processes which, by default, cannot simply share data afaik. Have a look at Sharing state between processes in the package's documentation to read about this. Especially take the first sentence into account: "when doing concurrent programming it is usually best to avoid using shared state as far as possible"!

So you might want to also have a look at Exchanging objects between processes to read about how to send/receive data between two different processes. So, instead of simply setting a flag to stop the loop, it might be better to send a message to signal the loop should be terminated.

Also note that processes are a heavyweight form of multiprocessing, they spawn multiple OS processes which comes with a relatively big overhead. multiprocessing 's main purpose is to avoid problems imposed by Python's Global Interpreter Lock (google about this to read more...) If your problem is'nt much more complex than what you've told us, you might want to use the threading package instead: threads come with less overhead than processes and also allow to access the same data (although you really should read about synchronization when doing this...)

I'm afraid, multiprocessing is an inherently complex subject. So I think you will need to advance your programming/python skills to successfully use it. But I'm sure you'll manage this, the python documentation about this is comprehensive and there are a lot of other resources about this.

To tackle your EDIT2 problem, you could try using the shared memory map Value .

import time
from multiprocessing import Process, Value

class Example():

  def func1(self, cond):
    while (cond.value == 1):
      print('do something')
      time.sleep(1)
    return

if __name__ == '__main__':

  ex = Example()
  cond = Value('i', 1)
  proc = Process(target=ex.func1, args=(cond,))

  proc.start()
  time.sleep(5)
  cond.value = 0
  proc.join()

(Note the target=ex.func1 without the parentheses and the comma after cond in args=(cond,) .)

But look at the answer provided by MartinStettner to find a good solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM