поэтому мой проект структурирован так, как следует. У меня есть вишневый сервер и серверный сервер, который выполняет некоторую операцию. Теперь у меня есть «основной» файл app.py, который обрабатывает эти процессы. Они начали как:странная ситуация с правами доступа к файлам на окнах
SERVER = subprocess.Popen([PYTHON_EXE_PATH, '-m', WEB_SERVER,
'tvb'], shell=False)
BACKEND = subprocess.Popen([PYTHON_EXE_PATH, '-m', 'bin.rpserver'
, cfg.RPC_SERVER_IP, cfg.RPC_SERVER_PORT],
shell=False)
Теперь после того, как они начали этот ИДП хранится в файл, так что пользователь может запустить сценарий остановки и закрыть их. Этот сценарий также хорошо работает и в основном:
def execute_stop():
if os.path.exists(PID_FILE):
pid_file = open(PID_FILE, 'r')
has_processes = False
for pid in pid_file.read().split('\n'):
if len(pid.strip()):
try:
if sys.platform == 'win32':
import ctypes
handle = ctypes.windll.kernel32.OpenProcess(1, False,
int(pid))
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
else:
os.kill(int(pid), signal.SIGKILL)
except Exception, _:
has_processes = True
if has_processes:
sys.stdout.write("Some old PIDs were still registered; \
They could not be stopped.")
pid_file.close()
pid_file = open(PID_FILE, "w")
pid_file.close()
Сейчас этот PID-файл, вместе с моим файлом регистратор и другими файлами данные, которые создаются проводится в cfg.STORAGE
, и я также имеет простую чистую процедуру, которая :
def execute_clean():
"""Remove TVB folder, TVB File DB, and log file."""
try:
if os.path.isdir(cfg.TVB_STORAGE):
shutil.rmtree(cfg.TVB_STORAGE)
except Exception, excep1:
sys.stdout.write("Could not remove storage folder!")
sys.stdout.write(str(excep1))
Это также отлично работает при вызове отдельно. Но вот в чем проблема: в моей программе есть опция, которая позволяет пользователю изменять некоторые настройки, и в этом случае вся программа должна перезагрузиться и шаги должны быть переделаны. Для этого я:
cherrypy.engine.exit()
self.logger.debug("Waiting for Cherrypy to terminate.")
sleep(2)
python_path = cfg().get_python_path()
proc_params = [python_path, '-m', 'bin.app', 'start', 'web', 'backend']
subprocess.Popen(proc_params, shell=False)
Так что это будет опять же в основном следующие шаги:
execute_stop()
execute_clean()
start both processes again
Странная вещь, что я не могу понять, что execute_stop()
работает отлично, и как вы можете видеть на конец PID_FILE
открыт в режиме записи и закрыт для очистки содержимого, но затем сразу после execute_clean()
не может сказать, что PID_FILE
заблокирован другим процессом.
Теперь я проверил и перепроверял, и каждый раз, когда этот файл открывается, он закрыт после, и я действительно не знаю, что искать. Это происходит только в окнах, и я пробовал использовать хост зависимостей, чтобы увидеть, что происходит, и кажется, что когда процессы python работают, зависимый ходок видит 4 ссылки и 2 обработчика для этих файлов, что странно, учитывая, что они закрываются каждый раз. Мне также кажется странным, что я могу открыть файлы в режиме 'w'
, но я не могу их удалить.
Любые идеи, что может быть неправильным/что искать, будут действительно оценены.
EDIT
Я пытался использовать в качестве мотивационные os.waitpid
, но при выполнении:
os.waitpid(int(pid), 0)
Я получил [Errno 10] No child processes
. Я также читал и видел, как кто-то говорит, что в окнах вы должны передать дескриптор вместо pid в os.waitpid, чтобы я также попробовал его с помощью дескриптора, но я получил тот же результат. Итак, в этот момент процесс больше не должен существовать?