Astranome

Стоп Поток

Jul 3rd, 2020
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.04 KB | None | 0 0
  1. Цитата Сообщение от Valimer Посмотреть сообщение
  2. убить процесс можно?
  3. Процесс - да.
  4. Поток - нет. Лицензия на убийство потоков есть только у ОС. Все другие способы - незаконны и караются изгнанием за Стену.
  5. Однако поток можно уведомить, чтобы он прекратил работу.
  6. Простая схема для уведомления 10 запущенных потоков, что пора бы им позавершаться.
  7.  
  8.  
  9. import threading
  10. import sys
  11. import time
  12.  
  13.  
  14. def worker(finished):
  15. x = 0
  16. name = threading.current_thread().name
  17. # работаем пока нам не намекнули что пора...
  18. while True:
  19. # проверяем установку флага для wait
  20. if finished.is_set():
  21. # что-то делаем для корректного завершения
  22. # освобождаем ресурсы, закрываем файлы и т.д.
  23.  
  24. print("Работа прервана. Сворачиваемся.",name,flush=True)
  25. return
  26.  
  27. #print(x)
  28. # имитируем работу потока
  29. time.sleep(3)
  30. x += 1
  31.  
  32. # дополнительное условие для нормального завершения потока
  33. if x > 10:
  34. # что-то делаем
  35. break
  36.  
  37. print('Нормальный конец работы',name)
  38. # уведомляем wait что можно больше не блокировать основной поток
  39. # а так как основной поток после wait ничего не делает - программа завершается
  40. finished.set()
  41.  
  42.  
  43. def killer(finished):
  44. '''убийца потоков...на самом деле всего лишь уведомитель'''
  45.  
  46. while True:
  47. if finished.is_set():
  48. print('Killer finished')
  49. return
  50. try:
  51. message = input(">>")
  52. # если написали в консоль exit
  53. if message == 'exit':
  54. name = input("[EXIT] Введите имя потока:\n")
  55. # уведомляем рабочий поток, что пора закругляться
  56. try:
  57. threads[name][0].set()
  58. except KeyError:
  59. pass
  60. except KeyboardInterrupt:
  61. # чтобы нельзя было завершить по Ctrl+C - иначе без этого потока
  62. # все остальные останутся неуправляемыми
  63. pass
  64.  
  65.  
  66. def main():
  67.  
  68. main_fin = threading.Event()
  69. killer_fin = threading.Event()
  70.  
  71. killer_t = None
  72.  
  73. '''
  74. # этот поток будет демоном, когда завершится недемонический рабочий поток
  75. # он помрет сам... да и пофиг, все равно ничего серьзного не делал :-)
  76. killer_t = threading.Thread(
  77. target=killer,
  78. daemon=True,
  79. name="killer",
  80. args=[killer_fin]
  81. )
  82. '''
  83. killer_t = killer_t or threading.current_thread()
  84. threads['killer'] = (killer_fin,killer_t)
  85. # создаем 10 рабочих лошадок
  86. # они будут обычными,
  87. # тогда мы получим возможность их уведомить о необходимости завершения
  88. # и они смогут произвести предварительные действия перед завершением
  89. for i in range(10):
  90. event = threading.Event()
  91. t_name = str(i)
  92. p2 = threading.Thread(
  93. target=worker,
  94. daemon=False, # не демон!
  95. name=t_name,
  96. args=[event]
  97. )
  98.  
  99. # коллекционируем потоки и события
  100. threads[t_name] = (event,p2)
  101.  
  102. # стартуем
  103. for _,p in threads.values():
  104. if not p.is_alive():
  105. p.start()
  106.  
  107. #ждем... или не ждем
  108. #for _,p in threads.values():
  109. # p.join()
  110.  
  111. # можно запускать киллера в основном потоке либо в отдельном потоке-демоне
  112. killer(killer_fin)
  113.  
  114. # ожидаем завершения основного рабочего потока
  115. #main_fin.wait()
  116. # если не ждем - после отработки все потоков-не-демонов программа завершается
  117. # если killer не демон, то программа остается работать, пока не уведомить
  118. # функцию killer о необходимости завершиться.
  119.  
  120.  
  121. if __name__ == "__main__":
  122. threads = {}
  123. main()
  124.  
  125. КодВыделить код
  126. >>exit
  127. [EXIT] Введите имя потока:
  128. 0
  129. >>Работа прервана. Сворачиваемся. 0
  130. exit
  131. [EXIT] Введите имя потока:
  132. 1
  133. >>Работа прервана. Сворачиваемся. 1
  134. exit
  135. [EXIT] Введите имя потока:
  136. 2
  137. >>exit
  138. [EXIT] Введите имя потока:
  139. Работа прервана. Сворачиваемся. 2
  140. 3
  141. >>Работа прервана. Сворачиваемся. 3
  142. Нормальный конец работы 5
  143. Нормальный конец работы 6
  144. Нормальный конец работы 7
  145. Нормальный конец работы 9
  146. Нормальный конец работы 8
  147. Нормальный конец работы 4
  148. exit
  149. [EXIT] Введите имя потока:
  150. killer
  151. Killer finished
Add Comment
Please, Sign In to add comment