Ниже следует делать то, что вы хотите:
import signal
import threading
from time import sleep
keep_running = True
def signal_handler(signal, frame):
global keep_running
keep_running = False
print("Received SIGINT\n")
signal.signal(signal.SIGINT,signal_handler)
def work():
while keep_running:
sleep(2)
print("Worker finished\n")
nbThreads = 2
threads = []
for i in range(nbThreads):
t = threading.Thread(target=work)
t.setDaemon(True)
t.start()
threads.append(t)
while any([t.isAlive() for t in threads]):
sleep(0.1)
Позволить эту программу запуска дает
Received SIGINT
Worker finished
Worker finished
Пояснение: Когда CTRL-C нажата программа получает signal.SIGINT
, который вызывает зарегистрированный обработчик signal_handler
назовем глобальную переменную keep_running
до False
. Тем временем основной поток ждет, пока все порожденные нити умрут. Таким образом, эти потоки могут закончить все, что они делали (в данном случае sleep
-ing), прежде чем основной поток завершится.
Примечание: Ожидание сигнала в Linux может быть достигнуто путем вызова signal.pause()
(заменив sleep(0.1)
). В Windows это невозможно, потому что эта функция не существует. Поэтому вышеуказанное должно быть менее зависимым от платформы.
Все, что мне нужно сделать, чтобы напечатать «рабочий закончен» во время его запуска, - это заменить последнюю строку «продолжить», верно? –
Что нужно заменить вместо того, чтобы рабочие печатали «рабочий закончен» и когда ctrl + C ударяли, чтобы они заканчивали .. и выходили? –
Потому что я хотел бы, чтобы функция work() запускалась еще до того, как нажата клавиша Ctrl + C. –