进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位
多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间.
创建进程的开销远大于线程
不同的进程之间是竞争关系,同一个进程的线程之间是合作关系
线程共享创建他的进程的地址空间,进程有自己的地址空间
线程可以直接访问其进程的数据段,进程有它们自己的父进程的数据段副本
线程可以直接与进程的其他线程通信,进程必须使用进程间通信来与兄弟进程通信
容易创建新线程,新进程需要父进程的复制
线程可以对同一进程的线程进行相当大的控制,流程只能对子流程进行控制
对主线程的更改(取消,优先级更改等)可能会影响进程中其他线程的行为.对父进程的更改不会影响子进程
多线程指的是,在一个进程中开启多个线程,
1.多线程共享一个进程的地址空间
2.线程比进程更加轻量级,线程比进程更容易创建和撤销
3.若多个线程都是cpu密集型的,那么并不能获得性能上的增强,如果需要大量的I/O处理,拥有多个线程允许这些活动彼此重叠运行,从而会加快程序执行的速度
4.在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小得多(不适用于python)
开启线程的两种方式:
1.通过继承Thread类,覆盖run方法,生成线程对象
2.调用Thread方法,为参数target指定目标,生成线程对象
Thread实例对象的方法:
isAlive():返回线程是否是活动的
getName():返回线程名
setName():设置线程名
threading模块提供的一些方法:
threading.currentThread():返回当前的线程变量
threading.enumerate():返回一个包含正在运行的线程的list,正在运行指线程启动后,结束前.不包括启动前和终止后的线程
threading.activeCount():返回正在运行的线程数量
1.对于主进程来说,运行完毕指的是主进程代码运行完毕
2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
主线程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束
主线程在其他非守护进程运行完毕后才算运行完毕(守护进程在此时就被回收),因为主进程结束意味着进程的结束.进程整体的资源都将被回收,而进程必须保证非守护进程都运行完毕后才能结束
锁通常被用来实现共享资源的同步访问,为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其他线程已经获得了该锁,则当前线程需等待其被释放,待资源访问完后再调用release方法释放锁
死锁:是指两个或两个以上的进程或线程都在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用将无法推进下去,此时称系统处于死锁状态或系统产生了死锁
信号量:其实也是一种锁,特点是可以设置一个数据可以被几个线程(进程)共享
Semaphore管理一个内置的计数器
每当调用acquire()时内置计数器减一,调用release()时内置计数器加一,计数器不能小于o,当计数器为零时,acquire()将阻塞线程直到其他线程调用release()
JoinableQueue(maxsize):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理,通知进程是使用共享的信号或条件变量来实现的
maxsize是队列允许最大项数,省略则无大小限制
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理,如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理,阻塞直将持续到队列中的每个项目均调用q.task_done()方法为止
多线程也是用于提高程序的效率,线程是程序的执行线路,进程包含线程,线程依赖进程