python多线程编程
笔记
多进程
多任务
Python可以多进程实习多任务
![]()
现在我们的系统就是多任务操作系统
多任务的优势
- 多任务的最大好处就是充分利用CPU资源,提高程序的执行效率
多任务的概念
多任务就是我们在同一时间可以执行多个任务
多任务执行执行方式
并发
并发就是CPU只有一个核处理多任务,系统程序轮流执行,就是并发
并行
并行就是CPU有多个核处理多任务,一个核处理一个任务,就是并行
进程
什么是进程
进行就是我们资源分配的最小单位,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位
上面说可能不太好理解,
咧
没有运行的程序叫程序
一个运行起来的程序叫做进行
操作系统会给他放屁cpu内存网络等资源

一个运行起来的程序必须有一个进程
多进程
在程序怎么实现多任务的方法,可以多进程
- 没有多进行py程序
- 他运行的时候只有一个住进程
- 多进程py程序
- 他运行的时候有多个子进程
py实现多进程
创建多任务
用到的包是multiprocessing
定义进程
1 | import multiprocessing |
multiprocessing.Process(targt=函数名, name,args,kwargs)
target 进行的多进程函数
name 可以选参数,设置进程名字,一般不不设置,他会有默认
args 元素的方式传参
kwargs 字典方式传输
group 进程组了解一下就可以了
演示代码
没有添加多进程的
1 | def a(): |
结果
1 | aaa |
添加了多进程的
1 | import multiprocessing |
结果
1 | aaa |
创建多任务传参
格式
1 | multiprocessing.Process(targt=函数名,args或kwargs) |
args 元素的方式传参
- 就是我们传的是按顺序来的
kwargs 字典方式传输
- 就是我们按参数名来的,指定参数名来传递
args元素
格式
1 | multiprocessing.Process(targt=函数名,args=(参数,)) |
args如果就一个参数的话后面要加上**,**应为说明他是一个元素
演示
1 | def a(a): |
结果
1 | aaa |
kwargs字典
格式
1 | multiprocessing.Process(targt=函数名,kwargs={参数的名:传参的内容}) |
kwargs这个他是按照参数名进行传递的
演示
1 | def a(a): |
结果
1 | aaa |
获取进程的编号
用到的是os模块
- os.getpid() 获得当前子进程的编号
- os.getppid() 获得父进程的编号
代码
1 | import multiprocessing |
结果
1 | 父进程38072 |
守护进程
什么是守护进程主进程关闭其他子进程自动关闭,默认不是
上面说可能不太好理解,比如QQ我们关闭QQ其他的聊天框就会全部关闭这个就是守护进程
python多进程默认不是,他是主进程会等待子进程关闭才会关闭主进程
演示
1 | import time |
结果:可以看见主进程执行完毕后主进程在等待子进程执行后在关闭程序
1 | 子进程 |
我们可以主进程执行后主进程就关闭程序
添加一个:主进程执行后主进程就关闭程序
1 | 定义进程对象.daemon=True |
代码
1 | import time |
结果
1 | 子进程 |
多线程
多线程也可以实现多任务
有了多进程为什么还要多线程那,应为一旦创建一个进程系统就会给这个进程分配资源
有一个进程才有线程,线程可以有多个或一个(必须有一个),线程是在进程里面的,全部的线程都可以共享这个进程的资源
一个程序能够包含多个进程,一个进程能够启动多个线程,线程才是真正工作的东西
py实现多线程
用到的包是threading,他和上面多进程库使用是一样的
定义进程
1 | import threading |
multiprocessing.Process(targt=函数名, name,args,kwargs)
target 进行的多线程函数
name 可以选参数,设置线程名字,一般不不设置,他会有默认
args 元素的方式传参
kwargs 字典方式传输
group 进程组了解一下就可以了
演示代码
没有添加多进程的
1 | def a(): |
结果
1 | aaa |
添加了多线程的
1 | import threading |
结果
1 | aaa |
后面就不演示了和多进程一样
多线程属性
threading我们只知道threading有一个start的开始属性
| 属性 | 作用 |
|---|---|
| xxx.start()属性 | 开始启动线程 |
| xxx.join()属性 | 阻塞线程直至线程终止,然后在继续运行 |
| xxx.daemon属性 | 守护进程,和上面一样 |
| xxx.getName()属性 | 获取线程名称 |
| xxx.setName()属性 | 用于设置线程的名称 |
join属性
阻塞线程直至线程终止,然后在继续运行
我自己的解释就是,一个进程里面有一个主线,和守护进程差不多,子线程没有执行完,主线程可能也会主线完
演示
1 | import threading |
结果,这个应为有了join()属性,只有duix1线程执行完后在执行这个duix2
1 | 执行第一个线程duix1 |
getName()属性
获取线程名称
1 | import threading |
结果
1 | Thread-1 |
setName()属性
1 | import threading |
结果
1 | abc |
线程安全
GIL锁
GIL,中文译为全局解释器锁,我们需要明确的一点是GIL并不是Python的特性,是CPython解释器的特性
GIL锁的作用就是,一个进程中只有一个线程被CPU调用,下一个枪到这个线程枪到这个GIL锁才可以用CPU
线程锁就像嫖妓一样的,你在外面等,别人出来了你才能进去
CPU多核优势,多线程就像嫖妓一样的,一个人玩一个,就可以利用的妓院小姐姐(多核CPU)人多多的优势了

