0

I want to make a subprocess(writer.py) that keeps adding "test" to a file('20180309.txt') every second and maintain the subprocess with another python process(starter.py).

It works fine, but one thing that bothers me is that the file object is not closed before terminating the subprocess. I'd like to know if there's a way to close the file object when the subprocess recieves terminate() signal, or if there are other ways to handle this problem.

#starter.py
import os
import sys
import subprocess

p1 = subprocess.Popen( ["d:\python36-32\python.exe", r"""writer.py"""], shell=False )
print(p1.pid)

try:
    p1.communicate(timeout=5)
except subprocess.TimeoutExpired:
    p1.terminate()




#writer.py
import time
from datetime import datetime

file = open( datetime.now().strftime('%Y-%m-%d') + '.txt', 'a')

while True:
    file.write('test\n')
    file.flush()
    time.sleep(1)
3
  • 1
    Assuming you're using Windows, *nix, or any other OS made in the last ~25 years, the OS will automatically close any files left open by a process when it goes away (except for files that are shared in some way—e.g., handed in by the parent, or less common cases like being passed over a Unix socket, WIn32 DuplicateHandle, etc.).
    – abarnert
    Commented Mar 9, 2018 at 0:28
  • 1
    Have you tried using multiprocessing for this instead of a subprocess? It's much cleaner for Python to Python communication and allows better control of the process.
    – Nebbles
    Commented Mar 9, 2018 at 1:12
  • @Nebbles Thank you for your advice. I thought a subprocess is part of multiprocessing. I will study on it!
    – maynull
    Commented Mar 9, 2018 at 22:11

1 Answer 1

1

First, any modern OS will close any (non-shared) files that a process has open when it goes away. You do not have to worry about this.

In a more complex application, you might want to worry about partial writes (or parts of any other "transactions" that can't be done atomically), but for simple cases, there's nothing to worry about at all.

Meanwhile, the terminate method in subprocess is not meant for polite shutdown requests. If you want to shut down the child, there are better ways to send it a message. In fact, since the child and parent are both Python, you may be happier using multiprocessing instead of subprocess in the first place.

That being said, on *nix, terminate happens to send SIGTERM, and SIGTERM is designed for polite shutdown. If you really want to handle this—and don't care about Windows—read the signal library for how to write a signal handler for SIGTERM. From the signal handler, you can set a global "quit next time through the loop" variable. or call sys.exit (which I think will raise an exception into the top-level code, but don't quote me on that), or whatever else you want.

1
  • Thank you for your detailed answer! I have learned a lot thanks to you!
    – maynull
    Commented Mar 9, 2018 at 22:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.