KeyboardInterrupt несколько потоков одновременно

В настоящее время я работаю с несколькими потоками для сбора данных и сохранения их в формате JSON. Цикл сбора данных бесконечен. Я хочу иметь возможность завершать все потоки с помощью CTRL+C. Поэтому я создал эту простую версию с двумя петлями. Я пробовал разные вещи, но пока не могу заставить это работать. Как я могу использовать «кроме KeyboardInterrupt», чтобы остановить оба цикла одновременно? Или есть лучший вариант?

import threading
from time import sleep

number = 0 
numberino = 10

def background():
    while True:
        if number < 10:
            global number
            number=number+1
            print number
            sleep(1)
        else:
            print "10 seconds are over!"
            break

def foreground():
    while True:
        if numberino > -10:
            global numberino
            numberino=numberino-1
            print numberino
            sleep(1)
        else:
            print "20 seconds are over!"
            break


b = threading.Thread(name='background', target=background)
f = threading.Thread(name='foreground', target=foreground)

b.start()
f.start()

person Zen_Master    schedule 16.06.2018    source источник
comment
Какую ОС вы используете? Вам действительно нужно делать это в Python 2?   -  person PM 2Ring    schedule 16.06.2018
comment
Я запускаю Debian на BeagleBone. Он просто поставляется с Python 2.7   -  person Zen_Master    schedule 16.06.2018


Ответы (1)


Самый простой способ сделать это — заставить ваши потоки проверять глобальный флаг, чтобы узнать, пора ли выйти. Общий принцип заключается в том, что вы не должны пытаться убивать потоки, вы должны попросить их выйти, чтобы они могли закрыть любые открытые ресурсы.

Я изменил ваш код, чтобы потоки (включая исходный поток) проверяли глобальный флаг alive. Кстати, вы не должны помещать директиву global в цикл, и она должна быть перед любой ссылкой на глобальные переменные, которые вы хотите изменить. Лучше всего разместить его в верхней части функции.

import threading
from time import sleep

number = 0 
numberino = 10
alive = True

def background():
    global number
    while alive:
        if number < 10:
            number += 1
            print number
            sleep(1)
        else:
            print "10 seconds are over!"
            break

def foreground():
    global numberino
    while alive:
        if numberino > -10:
            numberino -= 1
            print numberino
            sleep(1)
        else:
            print "20 seconds are over!"
            break

b = threading.Thread(name='background', target=background)
f = threading.Thread(name='foreground', target=foreground)

b.start()
f.start()

while alive:
    try:
        sleep(.1)
    except KeyboardInterrupt:
        alive = False

print 'Bye'
person PM 2Ring    schedule 16.06.2018
comment
Спасибо, это сработало отлично! Редактировать: Также спасибо за другой совет. - person Zen_Master; 18.06.2018