Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Цитата Сообщение от Valimer Посмотреть сообщение
- убить процесс можно?
- Процесс - да.
- Поток - нет. Лицензия на убийство потоков есть только у ОС. Все другие способы - незаконны и караются изгнанием за Стену.
- Однако поток можно уведомить, чтобы он прекратил работу.
- Простая схема для уведомления 10 запущенных потоков, что пора бы им позавершаться.
- import threading
- import sys
- import time
- def worker(finished):
- x = 0
- name = threading.current_thread().name
- # работаем пока нам не намекнули что пора...
- while True:
- # проверяем установку флага для wait
- if finished.is_set():
- # что-то делаем для корректного завершения
- # освобождаем ресурсы, закрываем файлы и т.д.
- print("Работа прервана. Сворачиваемся.",name,flush=True)
- return
- #print(x)
- # имитируем работу потока
- time.sleep(3)
- x += 1
- # дополнительное условие для нормального завершения потока
- if x > 10:
- # что-то делаем
- break
- print('Нормальный конец работы',name)
- # уведомляем wait что можно больше не блокировать основной поток
- # а так как основной поток после wait ничего не делает - программа завершается
- finished.set()
- def killer(finished):
- '''убийца потоков...на самом деле всего лишь уведомитель'''
- while True:
- if finished.is_set():
- print('Killer finished')
- return
- try:
- message = input(">>")
- # если написали в консоль exit
- if message == 'exit':
- name = input("[EXIT] Введите имя потока:\n")
- # уведомляем рабочий поток, что пора закругляться
- try:
- threads[name][0].set()
- except KeyError:
- pass
- except KeyboardInterrupt:
- # чтобы нельзя было завершить по Ctrl+C - иначе без этого потока
- # все остальные останутся неуправляемыми
- pass
- def main():
- main_fin = threading.Event()
- killer_fin = threading.Event()
- killer_t = None
- '''
- # этот поток будет демоном, когда завершится недемонический рабочий поток
- # он помрет сам... да и пофиг, все равно ничего серьзного не делал :-)
- killer_t = threading.Thread(
- target=killer,
- daemon=True,
- name="killer",
- args=[killer_fin]
- )
- '''
- killer_t = killer_t or threading.current_thread()
- threads['killer'] = (killer_fin,killer_t)
- # создаем 10 рабочих лошадок
- # они будут обычными,
- # тогда мы получим возможность их уведомить о необходимости завершения
- # и они смогут произвести предварительные действия перед завершением
- for i in range(10):
- event = threading.Event()
- t_name = str(i)
- p2 = threading.Thread(
- target=worker,
- daemon=False, # не демон!
- name=t_name,
- args=[event]
- )
- # коллекционируем потоки и события
- threads[t_name] = (event,p2)
- # стартуем
- for _,p in threads.values():
- if not p.is_alive():
- p.start()
- #ждем... или не ждем
- #for _,p in threads.values():
- # p.join()
- # можно запускать киллера в основном потоке либо в отдельном потоке-демоне
- killer(killer_fin)
- # ожидаем завершения основного рабочего потока
- #main_fin.wait()
- # если не ждем - после отработки все потоков-не-демонов программа завершается
- # если killer не демон, то программа остается работать, пока не уведомить
- # функцию killer о необходимости завершиться.
- if __name__ == "__main__":
- threads = {}
- main()
- КодВыделить код
- >>exit
- [EXIT] Введите имя потока:
- 0
- >>Работа прервана. Сворачиваемся. 0
- exit
- [EXIT] Введите имя потока:
- 1
- >>Работа прервана. Сворачиваемся. 1
- exit
- [EXIT] Введите имя потока:
- 2
- >>exit
- [EXIT] Введите имя потока:
- Работа прервана. Сворачиваемся. 2
- 3
- >>Работа прервана. Сворачиваемся. 3
- Нормальный конец работы 5
- Нормальный конец работы 6
- Нормальный конец работы 7
- Нормальный конец работы 9
- Нормальный конец работы 8
- Нормальный конец работы 4
- exit
- [EXIT] Введите имя потока:
- killer
- Killer finished
Add Comment
Please, Sign In to add comment