zoukankan      html  css  js  c++  java
  • 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之约束、加密及logging模块
    python之反射机制与callattr()、issubclass()、isinstance、type()相关
    python之面向对象初识
    python函数名的应用、闭包和迭代器
    python(动态传参、命名空间、函数嵌套、global和nonlocal关键字)
    python中函数的定义、返回值以及参数的简要介绍
    python文件操作
    python中set(集合),深浅拷贝以及一些补充知识点
    python中is与==的区别,编码和解码
    python数据类型:dict(字典)
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/6662271.html
Copyright © 2011-2022 走看看