1、进程、与线程区别
2、python GIL全局解释器锁
3、线程
- 语法
- join
- 线程锁之Lock\Rlock\信号量
- 将线程变为守护进程
- Event事件
- queue队列
- 生产者消费者模型
- Queue队列
- 开发一个线程池
4、进程
- 语法
- 进程间通讯
- 进程池
什么是进程(process)?
程序的执行实例称为进程。
每个进程都提供执行程序所需的资源。 进程具有虚拟地址空间,可执行代码,系统对象的打开句柄,
安全上下文,唯一进程标识符,环境变量,优先级类,最小和最大工作集大小以及至少一个执行线程。
每个进程都使用单个线程启动,通常称为主线程,但可以从其任何线程创建其他线程。
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。
程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;
进程是程序的一次执行活动,属于动态概念。
在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。
这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,
因此,进程就是为了在CPU上实现多道编程而提出的。
有了进程为什么还要线程?
进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。
很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,
主要体现在两点上:
-
进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
-
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
例如, 一个操作系统就像是一个工厂,工厂里面有很多个生产车间,不同的车间生产不同的产品,
每个车间就相当于一个进程,且你的工厂又穷,供电不足,同一时间只能给一个车间供电,
为了能让所有车间都能同时生产,你的工厂的电工只能给不同的车间分时供电,但是轮到你的qq车间时,
发现只有一个干活的工人,结果生产效率极低,为了解决这个问题,应该怎么办呢?
就是多加几个工人,让几个人工人并行工作,这每个工人,就是线程!
什么是线程(thread)?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,
每条线程并行执行不同的任务
线程是执行上下文,它是CPU执行指令流所需的所有信息。
假设你正在读一本书,而你现在想休息一下,但是你希望能够从你停下来的确切位置回来并继续阅读。
实现这一目标的一种方法是记下页码,行号和字号。因此,阅读书籍的执行环境就是这三个数字。
如果你有一个室友,并且她使用相同的技术,她可以在你不使用时拿走这本书,并从她停下的地方继续阅读。
然后你可以把它拿回来,并从你原来的地方恢复。
线程以相同的方式工作。 CPU正在给你一种错觉,即它同时进行多次计算。它通过在每次计算上花费一点时间来做到这一点。
它可以这样做,因为它具有每个计算的执行上下文。就像您可以与朋友共享一本书一样,许多任务可以共享CPU。
在更技术层面上,执行上下文(因此是一个线程)由CPU寄存器的值组成。
最后:线程与进程不同。线程是执行的上下文,而进程是与计算相关联的一堆资源。一个进程可以有一个或多个线程。
澄清:与进程相关联的资源包括内存页面(进程中的所有线程具有相同的内存视图),
文件描述符(例如,打开套接字)和安全凭证(例如,启动该进程的用户的ID)处理)。
进程与线程的区别?
1、线程共享创建它的进程的地址空间; 进程有自己的地址空间。
2、线程可以直接访问其进程的数据段; 进程拥有自己父进程数据段的副本。
3、线程可以直接与其进程的其他线程通信; 进程必须使用进程间通信来与兄弟进程通信。
4、新线程很容易创建; 新流程需要复制父流程。
5、线程可以对同一进程的线程进行相当大的控制; 进程只能控制子进程。
6、对主线程的更改(取消,优先级更改等)可能会影响进程的其他线程的行为; 对父进程的更改不会影响子进程。
Python GIL(Global Interpreter Lock)
在CPython中,全局解释器锁(GIL)是一个互斥锁,它可以防止多个本机线程同时执行Python字节码。
这种锁是必要的,主要是因为CPython的内存管理不是线程安全的。
(但是,由于GIL存在,其他功能已经增长,取决于它强制执行的保证。)
简而言之,无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行
GIL并不是Python的特性,Python完全可以不依赖于GIL
这篇文章透彻的剖析了GIL对python多线程的影响,强烈推荐看一下:http://www.dabeaz.com/python/UnderstandingGIL.pdf
Python threading模块
线程有2种调用方式,如下:
直接调用:
import threading import time def say_hi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=say_hi,args=(1,)) #生成一个线程实例 t2 = threading.Thread(target=say_hi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程 t2.start() #启动另一个线程 print(t1.getName()) #获取线程名 print(t2.getName())