what?

进程和线程的概念:

   进程是资源占用的最小单位 

   线程是内核调度执行的最小单位


进程和线程的主要区别:

   进程之间是彼此独立的,由master进程通过fork()系统调用派生子进程

   线程是共享内存空间的,主线程派生子线程


why?

进程和线程的优缺点:

   进程:

     优点:进程由于各自有独立的内存空间,所以更加稳定,子进程之间不受影响,但是主进程崩溃会导致全局,而且在python中不受GIL(全局解释器锁)限制,可以充分利用多核cpu

     缺点:对于内存资源占用比较高,而且创建一个进程的代价比线程要大

   线程:

     优点:由于共享内存空间,所以资源占用比较小,并且创建的代价小于进程,在python中受到GIL的限制,导致只能使用一个cpu核心,所以某一时刻运行的线程只有一个

     缺点:由于共享内存空间也导致了缺点,资源征用的问题(python中可以通过锁的机制限制),并且一个线程的崩溃可能导致整个进程崩溃


fork()系统调用:

   是unix/linux上比较特殊的一个系统调用,用于创建子进程,其特殊之处在于其他的系统调用函数一般调用一次返回一次,fork()调用一个返回两次(父进程pid+子进程pid),且fork()调用时返回的子进程pid永远为0


where?(python中考虑)

多进程和多线程的共同目标是实现多任务

任务类型:cpu密集型和io密集型

   cpu密集型:应该使用多进程,充分利用多核cpu实现真正意义上的并发执行

   io密集型:可以使用多线程,节约资源


how?

 在python中怎样使用多进程和多线程编程?

  1. 多线程

    python对于多线程的支持提供了两个基础库,较为底层的thread模块和较为高层的threading模块

    实现原理:

     将准备并发执行的代码当做参数传递给threading.Thread()创建一个线程对象,结合程序控制结构(循环)等方式来完成此线程对象start()的多次调用,从而实现多线程

     示例代码:(利用多线程实现并发socket通信服务端)

      import threading  ##导入线程库

      import socket    ##导入socket

      s=socket.socket()   #创建socket对象

      s.bind(('0.0.0.0',8888))   #绑定套接字

      s.listen(10)         #监听套接字

      def run():            #定义处理函数

         sock,addr=s.accept()

         while True:

             a=sock.recv(1024)

             if a:

                sock.send(a.upper())

             else:

                sock.close()

                break

      if __name__ =='__main__':

         for i in xrange(20):    #根据for循环创建20个线程

             t=threading.Thread(target=run)   #创建线程对象

             t.start()    #运行线程

      

      此示例的第二种写法:

      import threading  ##导入线程库

      import socket    ##导入socket

      s=socket.socket()   #创建socket对象

      s.bind(('0.0.0.0',8888))   #绑定套接字

      s.listen(10)         #监听套接字

      class Mythread(threading.Thread): 

          def run(self):            #定义处理函数

             sock,addr=s.accept()

             while True:

                 a=sock.recv(1024)

                 if a:

                    sock.send(a.upper())

                 else:

                    sock.close()

                    break

      if __name__ =='__main__':

         for i in xrange(20):    #根据for循环创建20个线程

             t=Mythread()   #创建线程对象

             t.start()    #运行线程

      

2.多进程

   python提供可multiprocessing模块中的Process类来创建进程对象,同时该模块还提供了Pool类来创建进程池对象,以及Queue和Pipe实现进程间通信

   实现原理:

      将准备并发执行的代码当做参数传递给multiprocessing.Process()创建一个进程对象,结合程序控制结构(循环)等方式来完成此进程对象start()的多次调用,从而实现多进程 

      示例代码:(利用多进程实现并发socket通信服务端)    

     

     import multiprocessing  ##导入线程库

      import socket    ##导入socket

      s=socket.socket()   #创建socket对象

      s.bind(('0.0.0.0',8888))   #绑定套接字

      s.listen(10)         #监听套接字

      def run():            #定义处理函数

         sock,addr=s.accept()

         while True:

             a=sock.recv(1024)

             if a:

                sock.send(a.upper())

             else:

                sock.close()

                break

      if __name__ =='__main__':

         for i in xrange(20):    #根据for循环创建20个线程

             t=multiprocess.Process(target=run)   #创建线程对象

             t.start()    #运行线程

 //可以使用ps aux | grep python 查看已经运行了20个进程

     同上:也可以自定义类并继承Process类再实例化对象的方式进行编写



总结:对于多任务的情形,并发是不可避免的问题,多进程和多线程可以实现并发,但是由于其都有不可避免的缺陷,所以如何让单进程或单线程实现并发任务的处理,如nginx,就需要使用异步IO的机制,基于事件驱动,在python中实现此机制的称为协程。