一、进程
1.定义
进程:程序的一次执行过程
每个进程都提供执行程序所需的资源。 进程具有虚拟地址空间,可执行代码,系统对象的打开句柄,安全上下文,唯一进程标识符,环境变量,优先级类别,最小和最大工作集大小以及至少一个执行线程。 每个进程都从单个线程(通常称为主线程)开始,但是可以从其任何线程中创建其他线程。
(1)直接调用
(2)继承式调用
3.进程间通讯
4.进程池
二、线程
1.定义
线程:操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
进程与线程的区别:
线程共享创建它的进程的地址空间; 进程具有自己的地址空间。
线程可以直接访问其进程的数据段。 流程具有其父进程数据段的副本。
线程可以直接与其进程中的其他线程通信。 进程必须使用进程间通信与同级进程进行通信。
新线程很容易创建; 新线程需要复制父线程。
线程可以对同一进程的线程进行相当多的控制。 进程只能控制子进程。
对主线程的更改(取消,优先级更改等)可能会影响该进程其他线程的行为; 对父进程的更改不会影响子进程。
线程可以直接访问其进程的数据段。 流程具有其父进程数据段的副本。
线程可以直接与其进程中的其他线程通信。 进程必须使用进程间通信与同级进程进行通信。
新线程很容易创建; 新线程需要复制父线程。
线程可以对同一进程的线程进行相当多的控制。 进程只能控制子进程。
对主线程的更改(取消,优先级更改等)可能会影响该进程其他线程的行为; 对父进程的更改不会影响子进程。
2.GIL(Global Interpreter Lock)
全局解释器锁:每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU,也就是说多线程并不是真正意义上的同时执行。
3.线程调用方式
(1)直接调用
import threading import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例 t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程 t2.start() #启动另一个线程 print(' ') print(t1.getName()) #获取线程名 print(t2.getName())
(2)继承式调用
import threading import time class MyThread(threading.Thread): def __init__(self,num): threading.Thread.__init__(self) self.num = num def run(self):#定义每个线程要运行的函数 print("running on number:%s" %self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start()
3.join
一些线程执行后台任务,例如发送keepalive数据包,执行定期垃圾回收等。 这些仅在主程序正在运行时才有用,并且可以在其他非守护程序线程退出后将其杀死。
如果没有守护程序线程,则必须跟踪它们,并告诉它们退出,然后程序才能完全退出。 通过将它们设置为守护程序线程,可以让它们运行并忘记它们,并且在程序退出时,所有守护程序线程都会自动终止。