是否可以在不设置/检查任何标志/信号量/等的情况下终止正在运行的线程?
我和我的朋友一直致力于一个大型项目,以便在python和PyGame中学习和娱乐.基本上它是一个小村庄的AI模拟.我们想要一个日/夜循环,所以我找到了一种利用numpy改变整个表面颜色的巧妙方法(特别是交叉渐变教程) - http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro. HTML
我将它实现到代码中并且工作正常,但速度非常慢,比如<1 fps slow.所以我看看线程(因为我想最终添加它)并在队列中找到这个页面 - 在python中学习队列模块(如何运行它)
我花了大约15分钟制作一个基本系统,但是一旦我运行它,窗口关闭,它说
Exception in thread Thread-1 (most likely raised during interpreter shutdown):
Run Code Online (Sandbox Code Playgroud)
编辑:这就是它所说的全部,没有回溯错误
我不知道我做错了什么,但我想我错过了一些简单的事情.我在下面添加了代码的必要部分.
q_in = Queue.Queue(maxsize=0)
q_out = Queue.Queue(maxsize=0)
def run(): #Here is where the main stuff happens
#There is more here I am just showing the essential parts
while True:
a = abs(abs(world.degree-180)-180)/400.
#Process world
world.process(time_passed_seconds)
blank_surface = pygame.Surface(SCREEN_SIZE)
world.render(blank_surface) #The world class renders everything onto a blank surface
q_in.put((blank_surface, a))
screen.blit(q_out.get(), (0,0))
def DayNight():
while True:
blank_surface, a = …Run Code Online (Sandbox Code Playgroud) 我已经看到了很多与此相关的问题...但我的代码适用于python 2.6.2并且无法在python 2.6.5上运行.我错误地认为整个atexit"通过这个模块注册的功能在程序被信号杀死时不被调用"这件事不应该在这里计算,因为我正在捕捉信号然后干净地退出?这里发生了什么?什么是正确的方法来做到这一点?
import atexit, sys, signal, time, threading
terminate = False
threads = []
def test_loop():
while True:
if terminate:
print('stopping thread')
break
else:
print('looping')
time.sleep(1)
@atexit.register
def shutdown():
global terminate
print('shutdown detected')
terminate = True
for thread in threads:
thread.join()
def close_handler(signum, frame):
print('caught signal')
sys.exit(0)
def run():
global threads
thread = threading.Thread(target=test_loop)
thread.start()
threads.append(thread)
while True:
time.sleep(2)
print('main')
signal.signal(signal.SIGINT, close_handler)
if __name__ == "__main__":
run()
Run Code Online (Sandbox Code Playgroud)
python 2.6.2:
$ python halp.py
looping
looping
looping …Run Code Online (Sandbox Code Playgroud) 我想在主程序停止时停止Python线程。它用于连接到服务器的类。连接由后台线程维护,前台线程响应回调。以下是一个最小的示例。
#!/usr/bin/python
import time, threading
class test():
running = False
def __init__(self):
print "init"
self.running = True
self.thread = threading.Thread(target = self.startThread)
self.thread.start()
def __del__(self):
running = False
print "del"
def startThread(self):
print "thread start"
while self.running:
time.sleep(1)
print "thread running"
a = test()
Run Code Online (Sandbox Code Playgroud)
当程序结束时,我天真地期望调用 __del__() 以便通知后台线程停止,但直到后台线程停止后才调用 i。显式调用某些函数不是一个选项,因为该类已被其他人使用,我不想强迫他们使用一些额外的代码行。
我有一个应用程序,每隔几分钟轮询一堆服务器.为此,它为每个服务器生成一个线程进行轮询(15个服务器)并将数据写回到对象:
import requests
class ServerResults(object):
def __init__(self):
self.results = []
def add_server(some_argument):
self.results.append(some_argument)
servers = ['1.1.1.1', '1.1.1.2']
results = ServerResults()
for s in servers:
t = CallThreads(poll_server, s, results)
t.daemon = True
t.start()
def poll_server(server, results):
response = requests.get(server, timeout=10)
results.add_server(response.status_code);
Run Code Online (Sandbox Code Playgroud)
该CallThreads班是一个辅助函数来调用一个函数(在这种情况下,poll_server()带有参数(在这种情况下s和results),你可以在我的GitHub库看到源Python的实用功能.大部分能正常工作的时间,但是有时候一个线程间歇我不知道为什么,因为我在GET请求上使用了超时.无论如何,如果线程挂起,则挂起的线程会在数小时或数天内累积,然后Python崩溃:
File "/usr/lib/python2.7/threading.py", line 495, in start
_start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread
Exception in thread Thread-575 (most likely raised during interpreter shutdown)
Exception in thread …Run Code Online (Sandbox Code Playgroud) 当我运行 python 程序(2.7 或 3)时,我导入一个模块,该模块具有初始化一些线程的类。问题是,每当主线程中发生未捕获的异常时,主函数就会死亡,但线程仍然像僵尸一样运行,导致 python 进程永远不会死亡。
在主线程(甚至其他线程)中存在任何未捕获的异常以杀死所有地方的所有内容的最佳方法是什么。
由于我经常调用该subprocess模块,所以我通常使用它threading.Event来帮助干净地退出。但是,未捕获的异常不会触发这些事件。
这是一个线程不会死的程序示例......
程序1.py
#!/usr/bin/env python2.7
import threading
import modx1
mod_obj = modx1.Moddy()
raise Exception('DIE UNEXPECTEDLY')
try:
raise Exception('known problem here')
except Exception:
mod_obj.kill_event.set()
Run Code Online (Sandbox Code Playgroud)
modx1.py
#!/usr/bin/env python2.7
import threading
import subprocess
from time import sleep
class Moddy():
def __init__(self):
self.kill_event = threading.Event()
self.my_thread=threading.Thread(target=self.thread_func)
self.my_thread.start()
def thread_func(self):
while not self.kill_event.is_set():
print('thread still going....')
sleep(2)
Run Code Online (Sandbox Code Playgroud) 我如何检查主线程是否从另一个(非守护程序,子线程)线程还存在?
子线程是非守护线程,我想检查Main线程是否仍在运行,并根据结果停止该非守护线程。
(使线程守护程序不适用于我的情况,因为stdout当线程设置为守护程序时,我的线程写入该线程会产生问题)
使用python 2.7
我很难理解为什么这个简单的程序最后会引发一个错误EOFError。
我正在使用与Queue()进行通讯,Thread()因此我想自动干净地终止atexit程序。
import threading
import multiprocessing
import atexit
class MyClass:
def __init__(self):
self.queue = None
self.thread = None
def start(self):
self.queue = multiprocessing.Queue()
self.thread = threading.Thread(target=self.queued_writer, daemon=True)
self.thread.start()
# Remove this: no error
self.queue.put("message")
def queued_writer(self):
while 1:
msg = self.queue.get()
print("Message:", msg)
if msg is None:
break
def stop(self):
self.queue.put(None)
self.thread.join()
instance = MyClass()
atexit.register(instance.stop)
# Put this before register: no error
instance.start()
Run Code Online (Sandbox Code Playgroud)
这引起了:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", …Run Code Online (Sandbox Code Playgroud) 我正在玩 python 3.7.4 上的线程,我想用它atexit来注册一个将(干净地)终止线程的清理函数。
例如:
# example.py
import threading
import queue
import atexit
import sys
Terminate = object()
class Worker(threading.Thread):
def __init__(self):
super().__init__()
self.queue = queue.Queue()
def send_message(self, m):
self.queue.put_nowait(m)
def run(self):
while True:
m = self.queue.get()
if m is Terminate:
break
else:
print("Received message: ", m)
def shutdown_threads(threads):
for t in threads:
print(f"Terminating thread {t}")
t.send_message(Terminate)
for t in threads:
print(f"Joining on thread {t}")
t.join()
else:
print("All threads terminated")
if __name__ == "__main__":
threads = [
Worker() …Run Code Online (Sandbox Code Playgroud)