简体   繁体   中英

Control running Python Process (multiprocessing)

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

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

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