初学 django,django 默认能否并发?

2018-11-21 14:44:24 +08:00
 lanqing

urls.py

    re_path(r'ceshi_uwsgi',view=views.test),
    re_path(r'ceshi_uwsgi2',view=views.test),

views.py

def test(request):
    time.sleep(5)
    return HttpResponse('ok')
def test2(request):
    time.sleep(5)
    return HttpResponse('ok')

启动方式

python manage.py runserver 0:8002

例 1:当我快速在浏览器两个窗口分别输入

http://localhost:8002/publisher/ceshi_uwsgi
http://localhost:8002/publisher/ceshi_uwsgi

给我的反应是一个窗口请求 5 秒执行完后再执行另外一个窗口请求,总共 10 秒

例 2:当我快速在浏览器两个窗口分别输入

http://localhost:8002/publisher/ceshi_uwsgi
http://127.0.0.1:8002/publisher/ceshi_uwsgi

给我的反应是基本上是同时执行 请求总共 5 秒中

我所理解的并发是 django 一个单线程的程序,一个请求没有结束是不能开始第二个请求(换句话就是不能并发),我后来给 django 配置了 uwsgi 服务器,结果还是像上述一样,我不太理解为什么会出现上面这种情况,希望大佬可以指点一二,感谢

11089 次点击
所在节点    Python
26 条回复
petelin
2018-11-22 17:40:33 +08:00
@Neojoke 另外 Python 的多线程是真的多线程, 只是有一把锁而已, 执行 Python 代码的时候要先拿到这把锁. 但是调用系统库那可是真的并行在跑
Neojoke
2018-11-22 18:11:24 +08:00
@petelin
我觉得吧,您让我学习一下的建议,我会接受的,但您是否考虑一下我的建议?
1. 翻翻 Python 解释器的源码,找找 CPython 的全局锁的实现代码。
这里给您奉上:
https://github.com/python/cpython/blob/e62a694fee53ba7fc16d6afbaa53b373c878f300/Python/ceval.c#L238
2. 考虑一下解释器作为共享资源,被全局锁保护以后,多线程代码在执行的时候,是否会被同步,在临界代码执行以后,才会被释放
3. 再思考一下,在什么特殊的情况下,会主动让出全局锁
4. PyThread_type_lock 这个看一下结构体,然后呢,自己做个试验,在多线程的情况下,模拟并发耗时操作,不断调高线程数,看一下总耗时是否和线程数的增加成正相关
5. 人家说的 Django,里面基本上是 Python 代码,几乎没有 C 的扩展调用,系统库也不都是用 C 实现的,C 实现的 io 操作是使用操作系统本身的线程、进程以及信号量来处理的。
Neojoke
2018-11-22 18:32:20 +08:00
楼主,没有人会使用 Django 默认的 runserver 进行生产部署的,并且官方文档也非常不推荐在生产环境使用 runserver 进行部署,原因就是 Python 虽然可以多线程,但是因为 CIL 的存在,导致其并发效率非常低,至于为什么很低,我前面已经把关键点罗列了一下。
生产环境部署 Python 的 Web 应用,有两种方式,一种是 uwsgi 使用多进程,多开 work,进行部署,一种是使用 gevent 协程实现非阻塞异步 I/O,但是我前面说了,这种要求,其他的代码也必须是非阻塞的编程模型。跟 nodejs 一样。
@111111111111 说的 runserver 是多线程的没有什么问题,能解决您的测试疑惑,但这里面最本质的还是要考虑,CIL 到底对并发有多大影响,GIL 一直起作用的时候,线程需要不断等待获取 GIL,线程被同步,但 I/O 操作的时候,Python 代码是会让出全局锁的,所以,多线程是有效的,可以考虑使用,但前提这是非阻塞的 I/O,也就说,C 底层提供的 I/O 功能,或者用 C 实现的非阻塞 I/O 功能,uwsgi 虽然是 C 写的,但不是非阻塞的,可以查看一下 C 的源码,如果不设置多个 work,就不能处理高并发,可以压测一下。试试
petelin
2018-11-22 18:58:42 +08:00
@Neojoke 你这不也承认多线程是有用的吗,还有什么好抬杠的。网站就是一个网络数据的处理,c 单线程估计也能完爆多线程的 python,python 的协程估计比多线程还强,这里面的思想不就是让 CPU 一直跑着去 handle 数据?数据流动比 CPU 处理速度慢多了
Neojoke
2018-11-22 21:18:36 +08:00
@petelin
前提都看不懂么?在非阻塞的情况下多线程能处理并发,阻塞代码基本上多线程没用
什么 C 单线程完爆 Python 多线程,还估计,说的是 C 的非阻塞 IO 代码能交还 GIL,不会引起 Python 多线程的同步等待,这也是 Python 伪并发的原因
这里的思想是 CPU 跑着 handle 数据?想表达什么?
数据流动比 CPU 处理速度快?数据流动是什么?
YuanGu333
2018-12-05 14:43:30 +08:00
有大佬开多一个贴再说明说明吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/510022

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX