1

I have yet another question about Python multiprocessing. I have a module that creates a Process and just runs in a while True loop. This module is meant to be enabled/disabled from another Python module. That other module will import the first one once and is also run as a process.

How would I better implement this?

so for a reference:

#foo.py

def foo():
  while True:
    if enabled:
      #do something

p = Process(target=foo)
p.start()

and imagine second module to be something like that:

#bar.py
import foo, time

def bar():
  while True:
    foo.enable()
    time.sleep(10)
    foo.disable()

Process(target=bar).start()

Constantly running a process checking for condition inside a loop seems like a waste, but I would gladly accept the solution that just lets me set the enabled value from outside. Ideally I would prefer to be able to terminate and restart the process, again from outside of this module. From my understanding, I would use a Queue to pass commands to the Process. If it is indeed just that, can someone show me how to set it up in a way that I can add something to the queue from a different module.

Can this even be easily done with Python or is it time to abandon hope and switch to something like C or Java

2

1 Answer 1

3

I purposed in comment two different approches :

  • using a shared variable from multiprocessing.Value
  • pause / resume the process with signals

Control by sharing a variable

def target_process_1(run_statement):
    while True:
        if run_statement.value:
            print "I'm running !"
            time.sleep(1)

def target_process_2(run_statement):
    time.sleep(3)
    print "Stoping"
    run_statement.value = False
    time.sleep(3)
    print "Resuming"
    run_statement.value = True

if __name__ == "__main__":
    run_statement = Value("i", 1)

    process_1 = Process(target=target_process_1, args=(run_statement,))
    process_2 = Process(target=target_process_2, args=(run_statement,))

    process_1.start()
    process_2.start()

    time.sleep(8)
    process_1.terminate()
    process_2.terminate()

Control by sending a signal

from multiprocessing import Process
import time
import os, signal

def target_process_1():
    while True:
        print "Running !"
        time.sleep(1)

def target_process_2(target_pid):
    time.sleep(3)
    os.kill(target_pid, signal.SIGSTOP)
    time.sleep(3)
    os.kill(target_pid, signal.SIGCONT)

if __name__ == "__main__":
    process_1 = Process(target=target_process_1)
    process_1.start()

    process_2 = Process(target=target_process_2, args=(process_1.pid,))
    process_2.start()

    time.sleep(8)

    process_1.terminate()
    process_2.terminate()

Side note: if possible do not run a while True.


EDIT: if you want to manage your process in two different files, supposing you want to use a control by sharing a variable, this is a way to do.

# file foo.py

from multiprocessing import Value, Process
import time

__all__ = ['start', 'stop', 'pause', 'resume']

_statement = None
_process = None

def _target(run_statement):
    """ Target of the foo's process """
    while True:
        if run_statement.value:
            print "I'm running !"
            time.sleep(1)

def start():
    global _process, _statement
    _statement = Value("i", 1)
    _process = Process(target=_target,  args=(_statement,))
    _process.start()

def stop():
    global _process, _statement
    _process.terminate()
    _statement, _process = None, _process

def enable():
    _statement.value = True

def disable():
    _statement.value = False
Sign up to request clarification or add additional context in comments.

3 Comments

This is a good solution, although I'm not sure how this can be implemented in two different files
thanks! So what does bar.py do? Is it as simple as importing foo and then using enable(), disable() etc?
The bar.py script is nearly the same that yours, except you must run foo.start() somewhere in your program before using foo.{dis|en}able().

Your Answer

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.