当前位置: 首页 > 面试题库 >

导入静默杀死线程

任长卿
2023-03-14
问题内容

我有一个简单的程序Base.py,可以测试import当模块不存在时是否能够引发异常。

# Base.py
import threading, os, time
import_is_working = False

class Launch(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()
    def run(self):
        global import_is_working
        try:
            print "Yes, it got into the 'try' block"
            import NON_EXISTENT_MODULE
            assert False
        except:
            print "Great, your python language is working"
            import_is_working = True
Launch()
for i in range(500):
    time.sleep(0.01)
    if import_is_working:
        break
if not import_is_working:
    print "Your import is not working."
    os._exit(4)

有时我喜欢在另一个模块中使用此代码Main.py

# Main.py
import Base

令人惊讶的是,当我以这种方式运行它时,它不起作用:

max% python Base.py
Yes, it got into the 'try' block
Great, your python language is working
max% python Main.py
Yes, it got into the 'try' block
Your import is not working.
max%

这种情况在Ubuntu中发生,并且在干净的CentOS 7.3中也发生。


问题答案:

您正在遇到“导入锁定”。

该文档提到了线程期间导入的限制,您违反了第一个限制(强调我的意思):

虽然导入机制是线程安全的,但是由于提供线程安全的方式存在固有的限制,因此对线程导入有两个关键限制:

首先,除了在主模块中之外, 导入不应具有产生新线程然后以任何方式等待该线程的副作用
。如果产生的线程直接或间接尝试导入模块,则不遵守此限制可能导致死锁。

其次,必须在解释程序开始关闭自身之前完成所有导入尝试。通过仅从通过线程模块创建的非守护程序线程执行导入,可以最轻松地实现这一点。守护程序线程和直接由线程模块创建的线程将需要某种其他形式的同步,以确保它们在系统关闭开始后不会尝试导入。不遵守此限制将导致间歇性异常并在解释器关闭期间崩溃(因为较晚的导入会尝试访问不再处于有效状态的机器)。



 类似资料:
  • 问题内容: 贝壳大师 我有一个bash shell脚本,其中启动了一个后台功能,例如,以显示一个无聊且冗长的命令的进度条: 现在,去世时,我看到以下文本: 这完全破坏了我本来非常棒的进度条显示的出色功能。 我如何摆脱此消息? 问题答案: 顺便说一句,我不知道您的进度栏多么酷,但是您看过Pipe Viewer(pv)吗? http://www.ivarch.com/programs/pv.shtml

  • 问题内容: 如何java.lang.Thread用Java 杀死A ? 问题答案: 有关他们为何不赞成使用Sun的内容,请参见此主题。它详细介绍了为什么这是一种不好的方法,以及通常应该采取什么措施才能安全地停止线程。 他们建议的方式是使用共享变量作为标志,要求后台线程停止。然后可以由另一个请求线程终止的对象来设置此变量。

  • 问题内容: 问题答案: 调用stop的替代方法是使用中断向线程发出信号,告知你希望它完成其工作。(这假设你要停止的线程行为良好,如果它在抛出异常后立即通过吃掉它们而忽略了InterruptedException,并且不检查中断状态,那么你将返回使用stop()。) 下面是一些代码,我写的一个答案,一个线程的问题在这里,它的线程中断,将如何工作的例子: 要注意的一些事情: 中断原因并立即抛出,否则你

  • 本文向大家介绍python杀死一个线程的方法,包括了python杀死一个线程的方法的使用技巧和注意事项,需要的朋友参考一下 最近在项目中遇到这一需求: 我需要一个函数工作,比如远程连接一个端口,远程读取文件等,但是我给的时间有限,比如,4秒钟如果你还没有读取完成或者连接成功,我就不等了,很可能对方已经宕机或者拒绝了。这样可以批量做一些事情而不需要一直等,浪费时间。 结合我的需求,我想到这种办法:

  • 我想使用执行器接口(使用Callable),以便启动一个线程(让我们称之为可调用线程),它将执行使用阻塞方法的工作。这意味着当主线程调用Future.cancel(true)(调用Thread.interrupt())时,可调用的线程可以抛出一个InterruptedExc0019。 我还希望我的可调用线程在代码的取消部分使用其他阻塞方法中断时正确终止。 在实现这一点时,我经历了以下行为:当我调用

  • 问题内容: 我正在使用命令在UNIX中查看JVM的线程转储。但是在哪里可以找到此命令的输出?我搞不清楚了!! 问题答案: 您也可以使用jstack(JDK附带)进行线程转储并将输出写入所需的任何位置。在Unix环境中不可用吗?