pythongil:Django save()是否阻塞?

2024-10-01 22:43:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我的django应用程序将django模型保存到远程数据库中。有时救人是突如其来的。为了将应用程序的主线程(*thread_A*)从将多个对象保存到数据库的时间开销中解放出来,我考虑使用^{}将模型对象传输到一个单独的线程(*thread_B*),并让*thread_B*按顺序保存它们。在

但我不确定这个计划。save()返回新数据库条目的id,因此它只有在数据库响应之后才“结束”,即在事务的末尾。在

在事务处理期间,django.db.models.Model.save()是否真的阻塞GIL并释放其他python线程?


Tags: 对象django模型目的数据库应用程序远程顺序
3条回答

Django的save()对GIL没有什么特别之处。事实上,在Python代码中,当GIL被执行时,几乎没有什么可以做的,线程必须保存GIL。在

只有两种方式可以释放GIL:

  • Python决定切换线程(在^{}指令之后)
  • Django调用一个数据库接口例程,实现该例程来释放GIL

第二点可能是您正在寻找的SQL COMMIT被执行,在执行期间,SQL后端发布GIL。然而,这取决于SQL接口,我不确定流行的接口是否真的发布了GIL*。在

而且,save()不仅仅运行几个UPDATE/INSERT语句和COMMIT;它在Python中做了大量的簿记工作,其中必须保存GIL。总之,我不确定将save()移动到另一个线程中是否会获得任何好处。在


更新:通过查看源代码,我了解到sqlite模块和psycopg在调用数据库例程时都会释放GIL,我想其他接口也会这样做。在

通常,您不必担心Django应用程序中的线程。如果您使用Apache、gunicorn或开发服务器以外的几乎任何其他服务器为应用程序提供服务,那么服务器将产生多个进程并完全避开GIL。例外情况是,如果您在gevent中使用gunicorn,在这种情况下,将有多个进程,但这些进程中也有微线程,在这种情况下,并发性会有所帮助,但您不必自己管理线程来利用它。唯一需要担心GIL的情况是,如果您试图生成多个线程来处理单个请求,这通常不是一个好主意。在

Django save()方法不会释放GIL本身,但是数据库后端会释放(在大多数情况下,save()所花费的大部分时间将用于数据库I/O)。然而,在一个设计良好的web应用程序中,要恰当地利用这一点几乎是不可能的。从你的角度来看,即使是同步完成的反应也应该很快,如果他们做了太多的工作而不能很快,那么用芹菜或其他监工来完成额外的工作。如果您尝试在视图中线程化,则必须在向客户端发送响应之前完成该线程,这在大多数情况下不会有任何帮助,只会增加额外的开销。在

我认为python本身不会锁定任何东西,但数据库可以。在

相关问题 更多 >

    热门问题