测试开发进阶(八)
并发和并行
多任务:操作系统可以同时运行多个任务。
并发:任务数>cpu核数,每个cpu快速切换任务
并行:任务数<cpu核数,每个cpu执行一个任务
多线程模块:threading
1 | import threading |
异步处理:
1 | import time |
threading模块
Thread类:
- run():用以表示线程活动的方法
- start():启动线程活动
- join([time]):设置主线程会等待time秒后再往下执行,time默认为子线程结束,多个子线程之间设置的值会增加
- isAlive():返回线程是否活动的
- getName():返回线程名
- setName():设置线程名
定义自己的Thread类
重写run方法
1 | def run(self): |
1 | # -*- coding:utf-8 -*- |
传参
在run方法中:
self._target(*self._args, **self._kwargs)
从Thread的init方法中可以看到
self._args = args
self._kwargs = kwargs
所以传递方式为修改args和kwargs的内容
1 | def __init__(self, group=None, target=None, name=None, |
普通方式传参
1 | def work1(name): |
自定义类方式传参
重写init方法:
1 | def __init__(self, url): |
1 | class MyThread(Thread): |
全局变量修改
多线程可以共用全局变量:使用的是同一块内存
会出现资源竞争
python中的线程是没办法进行并行执行,只能并发
线程之间什么时候会进行切换
- IO耗时操作:网络,文件,输入等耗时的IO操作,会自动切换
- 线程的执行时间到达一定的阈值,会自动切换
1 | # -*- coding:utf-8 -*- |
解决方案:
- 通过加锁来处理
- 通过队列来处理
1 | from threading import Thread, Lock |
GIL
- python语言和GIL没有关系,仅仅由于历史原因在于Cpython虚拟机(解释器),难以移出GIL
- GIL:全局解释器锁,每个线程在执行的过程中都需要获取GIL,保证同一时刻只有一个线程可以执行代码
- 线程释放GIL的情况,在IO操作等会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL,python3+使用计时器(执行时间达到阈值后,当前线程释放GIL),python2+,tickets计数达到100
- python使用多进程可以利用多核CPU资源
死锁
1 | from threading import Thread, Lock |