python web服务器学习笔记 并发尝试之popen原理探究

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python web服务器学习笔记 并发尝试之popen原理探究相关的知识,希望对你有一定的参考价值。

使用popen新开进程能实现并发吗?像这样的cgi处理程序

  def run_cgi(self,handler):
        cmd = "python" +handler.full_path
        child_stdin,child_stdout=os.popen2(cmd)
        child_stdin.close()
        data=child_stdout.read()
        child_stdout.close()
        handler.send_content(data)

 我让它跑

for i in range(1,100000):
    for i in range(1,1000000):
        1+1

 显然把它跑死了,运行这个cgi脚本的时候,服务器不能处理任何get请求

于是我就想是不是因为popen它要等待返回值输出的原因,然后我进行了如下改造

  def run_cgi(self,handler):
        cmd = "python" +handler.full_path
        child_stdin,child_stdout=os.popen2(cmd)
        cwd = "python" +"/usr/fuckbitch.py"
        stdin,stdout=os.popen2(cwd)
        child_stdin.close()
        data=child_stdout.read()
        child_stdout.close()
        handler.send_content(data)

 "/usr/fuckbitch.py"里就是那个能跑1000000万秒的死循环啦,然后服务器没死,它返回了cmd的页面,但cwd的死循环有没有同时运行呢

必须看清底层的原理才行,于是使用ps命令,查看进程

然后使用ps -T -p 26604查看进程下的线程,发现

  PID  SPID TTY          TIME      CMD

26604 26604 pts/0    00:00:18 python

而其他的

 PID  SPID TTY          TIME   CMD
26603 26603 pts/0    00:00:00 python <defunct>

这个跑了18秒的不就是我那个死循环程序吗,所以这是其实是成功了吗?

所以可以总结一下popen的用法。根据我们的实验,popen不是阻塞的。但当我们需要等待它的返回值的时候,我们的程序是阻塞的。并且popen的管道是有大小限制的。当输出的值超过管道大小65536时,popen会被阻塞,比如之前的实验中,我又把fuckbitch这个死循环改成了

for i in range(1,1000000):
    print "fuck"

 并等待它的返回。显然在通常的服务器上1s就能跑完了,可是服务器还是死了。原因可能是输出内容太过鬼畜(雾),搜了一下后发现是popen管道限制的原因


以上是关于python web服务器学习笔记 并发尝试之popen原理探究的主要内容,如果未能解决你的问题,请参考以下文章

Python Web学习笔记之并发编程的孤儿进程与僵尸进程

tornado学习笔记之HTTP请求及测试

dataquest学习笔记之 python web scrawl 之working with api

python 框架Flask学习笔记之session

python学习笔记第13章:web开发之sanic框架

python学习笔记第13章:web开发之sanic框架