返回信息流查了半天查到个方法,用的是ctypes.pythonapi.PyThreadState_SetAsyncExc()方法,
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(SystemExit))
但看ctypes下面的源码只能在windows和cygwin上运行,有其他办法吗
if _os.name in ("nt", "ce"):
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "cygwin":
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
else:
pythonapi = PyDLL(None)
这是一条镜像帖。来源:北邮人论坛 / python / #15432同步于 2016/8/10
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
python中主线程不结束时怎么结束子线程
chenxiansf
2016/8/10镜像同步10 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
抛一个异常应该就可以了吧?
参考: http://stackoverflow.com/questions/4541190/how-to-close-a-python-thread-from-within
这个逻辑是线程知道自己什么时候结束吧。我想的是主线程管理一些子线程,子线程都是死循环不结束的,然后由主线程来指定想要关闭某个线程。
我现在找了个折中的办法,就是设立全局变量并加锁,子线程的死循环中每做一件事前都读取这个变量,来决定要不要结束死循环。不过这样感觉有点麻烦,而且线程退出不够及时
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 抛一个异常应该就可以了吧?
: 参考: http://stackoverflow.com/questions/4541190/how-to-close-a-python-thread-from-within
用变量,让线程不断检测变量是否改变,是最好的,最干净的办法。也是Java语言推荐的办法。
不能强制终止一个线程:线程可能正处于一系列的嵌套的函数调用过程中。很可能有像try-finally或者with这样的需要“清理”的块存在。如果强行终止了,那些“清理”工作是得不到执行的。比如,一个线程正打开着一个文件,突然被别的线程干掉了,那没人会去关闭那个文件了。又如,一个线程正获得了一个锁,被干掉了,锁无法释放,然后就死锁了。总之会出各种问题。Java里,Thread.stop()被deprecate了。
Java推荐的做法是:每个线程有一个isInterrupted()标记,可以被别的线程用Thread.interrupt()方法来设置上。Java里所有可以阻塞等待的方法(比如Thread.sleep()),都会在被interrupt的时候抛出InterruptedException异常。如果是自己写方法,一般也应该在循环里不断检测Thread.isInterrupted(),如果是,就像库函数一样,也抛出InterruptedException。同时,用try-finally来关闭资源(比如文件)。
Python在多线程方面非常薄弱。毕竟从GIL开始的,一开始就没仔细考虑过多线程的问题。所以threading的API做得不尽人意,也并不奇怪。
重要的一点是,不要用锁。锁非常昂贵,而程序要在循环里不断检测中断标志,这个代价太高了。Java里,这个interrupt()方法和isInterrupted()方法很容易用不加锁的原子内存操作实现。毕竟Java的数据类型很低层,做一个可以原子更新和读取的boolean类型还是很容易的。Python里,全局变量其实是放在一个字典里的,修改一次要很多操作。不过,好在CPython解释器仅仅会在两个Python Bytecode之间释放GIL锁,所以也可以认为“设置一个全局变量的值”(STORE_GLOBAL)是原子的(起码对于Python线程来说是原子的)。
【 在 chenxiansf 的大作中提到: 】
: 这个逻辑是线程知道自己什么时候结束吧。我想的是主线程管理一些子线程,子线程都是死循环不结束的,然后由主线程来指定想要关闭某个线程。
: 我现在找了个折中的办法,就是设立全局变量并加锁,子线程的死循环中每做一件事前都读取这个变量,来决定要不要结束死循环。不过这样感觉有点麻烦,而且线程退出不够及时
另外,为什么要用Python写多线程的程序呢?
http://stackoverflow.com/questions/23547604/python-counter-atomic-increment#comment63972557_27062830
看到StackOverflow里有人这样回复:这些得到“原子性”的方法都是依赖目前的实现方法,而不是依赖Python语言和程序员之间的协议,即语言的specification。不过,Python的文档里确实说了GIL只会在Python的Bytecode之间释放(https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe),但Python的Bytecode是CPython这个实现特有的,是不能依赖的,而且文档明确说了以后有可能会修改(https://docs.python.org/3.5/library/dis.html)。
换句话说,Python没有一个可靠而且高效的写多线程程序的方法。要不要考虑换个语言?
多谢暖神指点。不换了,将就用,虽然性能上低点,就当性能换开发效率了
【 在 nuanyangyang 的大作中提到: 】
: 另外,为什么要用Python写多线程的程序呢?
: http://stackoverflow.com/questions/23547604/python-counter-atomic-increment#comment63972557_27062830
: 看到StackOverflow里有人这样回复:这些得到“原子性”的方法都是依赖目前的实现方法,而不是依赖Python语言和程序员之间的协议,即语言的specification。不过,Python的文档里确实说了GIL只会在Python的Bytecode之间释放(https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe),但Python的Bytecode是CPython这个实现特有的,是不能依赖的,而且文档明确说了以后有可能会修改(https://docs.python.org/3.5/library/dis.html)。
: ...................