在理解进程和线程概念以前首选要对并发有必定的感性认识,若是服务器同一时间内只能服务于一个客户端,其余客户端都再那里傻等的话,可见其性能的低下估计会被客户骂出翔来,所以并发编程应运而生,并发是网络编程中必须考虑的问题。实现并发的方式有多种:好比多进程、多线程、IO多路复用。面试
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会建立一个进程,并为它分配资源,而后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。编程
Linux系统函数fork()
能够在父进程中建立一个子进程,这样的话,在一个进程接到来自客户端新的请求时就能够复制出一个子进程让其来处理,父进程只需负责监控请求的到来,而后建立子进程让其去处理,这样就能作到并发处理。服务器
# -*- coding:utf-8 -*- import os print('当前进程:%s 启动中 ....' % os.getpid()) pid = os.fork() if pid == 0: print('子进程:%s,父进程是:%s' % (os.getpid(), os.getppid())) else: print('进程:%s 建立了子进程:%s' % (os.getpid(),pid ))
输出结果:网络
当前进程:27223 启动中 .... 进程:27223 建立了子进程:27224 子进程:27224,父进程是:27223
fork函数会返回两次结果,由于操做系统会把当前进程的数据复制一遍,而后程序就分两个进程继续运行后面的代码,fork分别在父进程和子进程中返回,在子进程返回的值pid永远是0,在父进程返回的是子进程的进程id。多线程
线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程能够由不少个线程组成,线程间共享进程的全部资源,每一个线程有本身的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就容许多个线程同时运行。一样多线程也能够实现并发操做,每一个请求分配一个线程来处理。并发
进程是资源分配的最小单位,线程是程序执行的最小单位。less
进程有本身的独立地址空间,每启动一个进程,系统就会为它分配地址空间,创建数据表来维护代码段、堆栈段和数据段,这种操做很是昂贵。而线程是共享进程中的数据的,使用相同的地址空间,所以CPU切换一个线程的花费远比进程要小不少,同时建立一个线程的开销也比进程要小不少。函数
线程之间的通讯更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通讯须要以通讯的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。性能
可是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另一个进程形成影响,由于进程有本身独立的地址空间。ui
老外的原话是这么说的 —-《Unix网络编程》:
fork is expensive. Memory is copied from the parent to the child, all descriptors are duplicated in the child, and so on. Current implementations use a technique called copy-on-write, which avoids a copy of the parent’s data space to the child until the child needs its own copy. But, regardless of this optimization, fork is expensive.
IPC is required to pass information between the parent and child after the fork. Passing information from the parent to the child before the fork is easy, since the child starts with a copy of the parent’s data space and with a copy of all the parent’s descriptors. But, returning information from the child to the parent takes more work.
Threads help with both problems. Threads are sometimes called lightweight processes since a thread is “lighter weight” than a process. That is, thread creation can be 10–100 times faster than process creation.
All threads within a process share the same global memory. This makes the sharing of information easy between the threads, but along with this simplicity comes the problem