我有一些函数可以使用 __import__ 以交互方式加载 python 模块
我最近偶然发现了一些关于 Python 中的“导入锁”的文章,即专门针对导入(不仅仅是 GIL)的锁。但这篇文章已经过时了,所以可能不再是这样了。
这让我想知道在线程中导入的做法。
import/__import__ 线程安全吗?2012 年 9 月 12 日编辑
感谢 Soravux 的精彩回复。
所以 import 是线程安全的,我不用担心死锁,因为在我的代码中使用 __import__ 的函数不会互相调用。
你知道即使模块已经被导入了,是否也获得了锁?
如果是这种情况,我应该在调用 __import__ 之前查看 sys.modules 以检查模块是否已经导入。
当然,这在 CPython 中不会产生太大差异,因为无论如何都有 GIL。 然而,它可能会对其他实现(如 Jython 或无堆栈 python)产生很大影响。
2012 年 9 月 19 日编辑
关于 Jython,这是他们在文档中所说的内容:
http://www.jython.org/jythonbook/en/1.0/Concurrency.html#module-import-lock
Python does, however, define a module import lock, which is implemented by Jython. This lock is acquired whenever an import of any name is made. This is true whether the import goes through the import statement, the equivalent
__import__builtin, or related code. It’s important to note that even if the corresponding module has already been imported, the module import lock will still be acquired, if only briefly.
因此,在进行导入之前检查 sys.modules 似乎是有意义的,以避免获取锁。你怎么看?
最佳答案
更新:从 Python 3.3 开始,导入锁是每个模块而不是全局的,并且 imp 被弃用,取而代之的是 importlib .有关 changelog 的更多信息和 this issue ticket .
下面的原始答案早于 Python 3.3
普通导入是线程安全的,因为它们在执行前获取一个导入锁,并在导入完成后释放它。如果您使用可用的 Hook 添加自己的自定义导入,请务必将此锁定方案添加到其中。 Python 中的锁定功能可以通过 imp 模块访问 (imp.lock_held()/acquire_lock()/release_lock())。 编辑:自 Python 3.3 起已弃用,无需手动处理锁。
除了 already known 的循环依赖之外,使用这个导入锁不会产生任何死锁或依赖错误。 (模块 a 导入模块 b,后者导入模块 a)。 编辑:Python 3.3 更改了每个模块的锁定机制,以防止循环导入引起的死锁。
有多种创建新进程或线程的方法,例如fork和 clone (假设是 Linux 环境)。在创建新进程时,每种方式都会产生不同的内存行为。默认情况下,fork 复制大部分内存段(数据(通常是 COW)、堆栈、代码、堆),实际上不在子进程和父进程之间共享其内容。 clone(通常称为线程,Python 将其用于线程)的结果与其父级共享除堆栈之外的所有内存段。 Python 中的导入机制使用不放在堆栈上的全局命名空间,因此在其线程之间使用共享段。这意味着一个线程中的 import 执行的所有内存修改(堆栈除外)将对其所有其他相关线程和父线程可见。如果导入的模块仅适用于 Python,则它在设计上是线程安全的。如果导入的模块使用非 Python 库,请确保它们是线程安全的,否则它将在您的多线程 Python 代码中造成困惑。
顺便说一句,Python 中的线程程序会遇到 GIL除非您的程序受 I/O 限制或依赖 C 或外部线程安全库(因为它们应该在执行前释放 GIL),否则不会带来太多性能提升。由于此 GIL,在两个线程中运行相同的导入 Python 函数将不会同时执行。请注意,这只是 CPython 的限制,其他 Python 实现可能有不同的行为。
回答您的编辑:导入的模块全部由 Python 缓存。如果模块已经加载到缓存中,则不会再次运行,导入语句(或函数)将立即返回。您不必自己在 sys.modules 中实现缓存查找,Python 会为您完成,并且不会 imp 锁定任何东西,除了用于 sys.modules 查找的 GIL。
回答您的第二次编辑:我宁愿维护更简单的代码,也不愿尝试优化对我使用的库(在本例中为标准库)的调用。理由是执行某事所需的时间通常比导入执行该操作的模块所需的时间重要得多。此外,在整个项目中维护此类代码所需的时间远远高于执行所需的时间。这一切都归结为:“程序员时间比 CPU 时间更有值(value)”。
关于python - 在 Python 线程中导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12389526/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem