我最近注意到在python的不同包中有两个不同的信号量实现,一个在threading包中,另一个在asyncio包中。我很好奇,这两种实现有什么区别?如果在异步函数中,我尝试使用threading包中的信号量,这会导致任何潜在的问题吗?
通过查看python官方文档,它编写了
asyncio primitives are not thread-safe, therefore they should not be used for OS thread synchronization (use threading for that)但是说asyncio primitives are not thread-safe and should not be used for OS thread sync是什么意思呢?
提前感谢
发布于 2021-10-24 16:48:18
信号量的整个目标是提供对某些事物的独占访问。在任何时候,只有一个“代码段”可以访问自己的信号量。
我在前面的语句中所说的“代码段”是指什么,取决于我是使用多线程、多线程还是异步。你保证独家访问的方式取决于我使用的是什么。
Asyncio是最受限制的多线程类型.所有东西都在一个Python线程中运行。Python解释器一次只执行一件事情。每个“代码段”都会运行,直到它自愿地等待发生一些事情。然后允许运行另一段“代码”。最终,当它等待的事情发生时,原始代码段会再次运行。
通过多线程,Python解释器中正在运行多个代码段。任何时候都只运行一段代码,但它们之间没有礼貌地等待。Python根据需要从“代码段”切换到“代码段”。
通过多处理,多个Pythons同时运行。除了操作系统提供的内容之外,代码片段之间没有共享。要设置信号量,通常需要操作系统提供一定的支持,以创建所有线程/进程都可以访问的共享变量。
所以。Asyncio原语的设计使得它们都在一个Python进程中运行,并与进程协作。如果多个代码试图同时使用这些代码,它们就无法工作。
我希望这能帮到你。
发布于 2021-10-24 17:02:14
您没有选择使用哪个队列或哪个信号量。它们是不相容的。
即使它们都提供并发性,asyncio和多线程实际上是两个完全不同的世界,基于不同的原则和API,有不同的典型用例,等等。
多线程程序的开发并不容易,一个名为GIL的Python特性使它们变得不那么高效。这使得异步成为首选,除非您被迫使用多线程。
尽管如此,这两种方法都可以在一个程序中使用。
在多线程应用程序的一个线程中运行异步代码是可能的,但并不常见。引用的docs通知提醒您,几乎所有异步操作都必须在该线程内执行。只有很少的专门的线程安全的低级调度函数。
为了实现完备性,asyncio库可以利用线程池进行内部使用,因为异步程序不应该执行所谓的阻塞操作。
https://stackoverflow.com/questions/69698479
复制相似问题