import inside of a Python thread

血红的双手。 提交于 2019-11-30 18:14:47

Normal imports are thread safe because they acquire an import lock prior to execution and release it once the import is done. If you add your own custom imports using the hooks available, be sure to add this locking scheme to it. Locking facilities in Python may be accessed by the imp module (imp.lock_held()/acquire_lock()/release_lock()).

Using this import lock won't create any deadlocks or dependency errors aside from the circular dependencies that are already known.

The low-level call to create a thread being clone on Linux, threading in Python is then a fork-like operation. Forking and cloning applies different behaviors on the various memory segments. For exemple, only the stack is not shared by threads, compared to forks which clones more segments (Data (often COW), Stack, Code, Heap), effectively not sharing its content. The import mechanism in Python uses the global namespace which is not placed on the stack, thus using a shared segment with its threads. Since the side-effects (ie. the changes in memory) of importing works in the same segments, it behaves as a single-threaded program. Be careful to use thread safe libraries in your imports on multithreaded programs, though. It will cause mayhem to use calls to functions that are not thread safe in such environment.

By the way, threaded programs in Python suffers the GIL which won't allow much performance gains unless your program is I/O bound or rely on C or external thread-safe libraries (since they release the GIL before executing). Running in two threads the same imported function won't execute concurrently because of this GIL. Note that this is only a limitation of CPython and other implementations of Python will have a different behavior.

To answer your edit: imported modules are all cached by Python. If the module is already loaded in the cache, it won't be run again and the import statement (or function) will return right away. You don't have to implement yourself the cache lookup in sys.modules, Python does that for you and won't imp lock anything, aside from the GIL for the sys.modules lookup.

To answer your second edit: I prefer having to maintain a simpler code than trying to optimize calls to the libraries I use (in this case, the standard library). The rationale is that the time required to perform something is usually way more important than the time required to import the module that does it. Furthermore, the time required to maintain this kind of code throughout the project is way higher than the time it will take to execute. It all boils down to: "programmer time is more valuable than CPU time".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!