У меня есть короткий скрипт на python, который должен:
- может использоваться многими пользователями и потоками одновременно,
- вызов другой программы (
/usr/bin/ld
)
- вызывайте эту другую программу не более x раз одновременно (например, 2 одновременных вызова
ld
)
- ручка прерывается / убивается
Мне удалось добиться большей части этого, используя общий семафор из модуля Python posix_ipc . Он обрабатывает SIGTERM
и ctrl+c
- семафор освобожден, но он не обрабатывает SIGKILL
- семафор остается полученным и должен быть сброшен вручную. Это означает, что выполнение kill -9
дважды отключает его навсегда (пока не будет применено ручное исправление).
Как освободить семафор, когда скрипт убит? Если не возможно - есть ли другой метод для достижения аналогичного результата?
Я изучил блокировки файлов (предполагая, что число одновременных использований всегда будет равно 2) - возможно, у меня может быть 2 файла, попробуйте заблокировать 1, если не удалось заблокировать другой, и подождите, пока не станет доступным. Но я не мог понять, как сделать «попытаться заблокировать, если sb else уже заблокировал его, сделайте что-то еще».
Полный код скрипта:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import posix_ipc
import subprocess
import sys
import signal
SEM_NAME = '/serialize_ld'
MAX_CONCURRENT = 1
PROGRAM = '/usr/bin/ld'
def main():
import os
os.umask(0)
sem = posix_ipc.Semaphore(SEM_NAME, posix_ipc.O_CREAT, mode=0o666, initial_value=MAX_CONCURRENT)
sem.acquire()
def release_semaphore(signum, frame):
print("exiting due to signal " + str(signum))
sem.release()
sem.close()
sys.exit(1)
signal.signal(signal.SIGTERM | signal.SIGINT | signal.SIGKILL, release_semaphore)
try:
subprocess.call([PROGRAM, *sys.argv[1:]])
finally:
sem.release()
sem.close()
if __name__ == "__main__":
main()