首页 > 代码库 > python web服务器学习笔记(五) 并发尝试之popen原理探究

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=http://www.mamicode.com/child_stdout.read()>

 我让它跑

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=http://www.mamicode.com/child_stdout.read()>

 "/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原理探究