Skip to content

Commit a459de9

Browse files
committed
Use a simpler and more straightforward method to terminate the process tree
1 parent f314965 commit a459de9

File tree

5 files changed

+20
-58
lines changed

5 files changed

+20
-58
lines changed

cyaron/io.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
from __future__ import absolute_import
88
import os
99
import re
10+
import signal
1011
import subprocess
1112
import tempfile
12-
import psutil
13-
from typing import Union, overload, Optional, List
13+
from typing import Union, overload, Optional, List, cast
1414
from io import IOBase
1515
from . import log
1616
from .utils import list_like, make_unicode
@@ -91,6 +91,7 @@ def __init__( # type: ignore
9191
# if the dir "./io" not found it will be created
9292
"""
9393
self.__closed = False
94+
self.input_file = cast(IOBase, None)
9495
self.output_file = None
9596
if file_prefix is not None:
9697
# legacy mode
@@ -230,20 +231,13 @@ def __clear(self, file: IOBase, pos: int = 0):
230231
file.seek(pos)
231232

232233
@staticmethod
233-
def _kill_process_and_children(pid: int):
234-
try:
235-
parent = psutil.Process(pid)
236-
while True:
237-
children = parent.children()
238-
if not children:
239-
break
240-
for child in children:
241-
IO._kill_process_and_children(child.pid)
242-
parent.kill()
243-
except psutil.NoSuchProcess:
244-
pass
245-
except psutil.AccessDenied:
246-
pass
234+
def _kill_process_and_children(proc: subprocess.Popen):
235+
if os.name == "posix":
236+
os.killpg(os.getpgid(proc.pid), signal.SIGKILL)
237+
elif os.name == "nt":
238+
os.system(f"TASKKILL /F /T /PID {proc.pid} > nul")
239+
else:
240+
proc.kill() # Not currently supported
247241

248242
def input_write(self, *args, **kwargs):
249243
"""
@@ -304,13 +298,14 @@ def output_gen(self,
304298
stdin=self.input_file.fileno(),
305299
stdout=subprocess.PIPE,
306300
universal_newlines=replace_EOL,
301+
preexec_fn=os.setsid if os.name == "posix" else None,
307302
)
308303

309304
try:
310305
output, _ = proc.communicate(timeout=time_limit)
311306
except subprocess.TimeoutExpired:
312-
# proc.kill() # didn't work because `shell=True`.
313-
self._kill_process_and_children(proc.pid)
307+
# proc.kill() # didn't work because `shell=True`.
308+
self._kill_process_and_children(proc)
314309
raise
315310
else:
316311
if replace_EOL:

cyaron/tests/io_test.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ def test_output_gen(self):
7676

7777
def test_output_gen_time_limit_exceeded(self):
7878
with captured_output():
79+
TIMEOUT = 0.02
80+
WAIT_TIME = 0.4 # If the wait time is too short, an error may occur
7981
with open("long_time.py", "w", encoding="utf-8") as f:
8082
f.write("import time, os\n"
8183
"fn = input()\n"
82-
"time.sleep(0.1)\n"
84+
f"time.sleep({WAIT_TIME})\n"
8385
"os.remove(fn)\n")
8486

8587
with IO("test_gen.in", "test_gen.out") as test:
@@ -89,8 +91,8 @@ def test_output_gen_time_limit_exceeded(self):
8991
with self.assertRaises(subprocess.TimeoutExpired):
9092
test.input_writeln(abs_input_filename)
9193
test.output_gen(f'"{sys.executable}" long_time.py',
92-
time_limit=0.05)
93-
time.sleep(0.1)
94+
time_limit=TIMEOUT)
95+
time.sleep(WAIT_TIME)
9496
try:
9597
os.remove(input_filename)
9698
except FileNotFoundError:
@@ -133,10 +135,7 @@ def test_make_dirs(self):
133135

134136
mkdir_false = False
135137
try:
136-
with IO(
137-
"./automkdir_false/data.in",
138-
"./automkdir_false/data.out",
139-
):
138+
with IO("./automkdir_false/data.in", "./automkdir_false/data.out"):
140139
pass
141140
except FileNotFoundError:
142141
mkdir_false = True

poetry.lock

Lines changed: 1 addition & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ readme = "README.md"
1010
python = ">=3.6"
1111
xeger = "^0.4.0"
1212
colorful = "^0.5.6"
13-
psutil = "^6.1.0"
1413

1514

1615
[build-system]

tox.ini

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ isolated_build = true
77
deps =
88
xeger
99
colorful
10-
psutil
1110
commands = python unit_test.py
1211
allowlist_externals = poetry

0 commit comments

Comments
 (0)