0

I am making a python module to help manage some tasks in Linux (and BSD) - namely managing Linux Containers. I'm aware of a couple of the ways to run terminal commands from python, such as Popen(), call(), and check_call(). When should I use these specific functions? More specifically, when is it proper to use the blocking or non-blocking function?

I have functions which build the commands to be run, which then pass the command (a list) to another function to execute it, using Popen.

Passing a command such as:

['lxc-start', '-n', 'myContainer']

to

...
def executeCommand(command, blocking=False):
    try:
        if blocking:
            subprocess.check_call(command)
        else:
            (stdout, stderr) = Popen(command, stdout=PIPE).communicate()
            self.logSelf(stdout)
    except:
        as_string = ' '.join(command)
        logSelf("Could not execute :", as_string) #logging function
    return
...

the code defaults to using Popen(), which is a non-blocking function. Under which kinds of cases should I override blocking and let the function perform check_call()?

My initial thoughts were to using blocking when the process is a one-time temporary process, such as the creation of the container, and to use non-blocking when the process is continuously running, such as starting a container.

Am I understanding the purpose of these functions correctly?

galois
  • 825
  • 2
  • 11
  • 31
  • 1
    Note that `Popen(...).communicate()` is a blocking call. You don't have any non-blocking calls in your example. The deciding factor is whether the calling code wants to run in parallel with the command being executed. – tdelaney Dec 23 '14 at 04:37
  • Also, note that `check_call()` very specifically checks the result code, as the name clearly reveals. That's useful if that's what you want, but frequently seems to be used erroneously by people who don't want a traceback if the shell command returns a non-zero exit code (and who then write here to gripe about this obvious and documented behavior). – tripleee Dec 23 '14 at 05:04
  • Is Popen() without .communicate() a non-blocking call? – galois Dec 23 '14 at 05:27

1 Answers1

1

To answer the wider question - I would suggest :

Use a blocking call when you are doing something which either :

  1. You know will always be quick - regardless of whether it works or fails.
  2. Something which is critical to your application, and where is make no sense for your application to do anything else unless and until that task is complete - for instance connecting to or creating critical resources.

Use non-blocking calls in all other cases if you can, and especially if :

  1. The task could take a while or
  2. It would be useful to be doing something else while the task executes (even if that is a gui update to show progress).
Tony Suffolk 66
  • 9,358
  • 3
  • 30
  • 33