[TOC=1,5]
>[success] # 线程和进程
~~~
1.线程是操作系统能够进行运算调度的最小单位。
2.他被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中的一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程并行执行不同的任务。
3.进程:要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,堆存的管理,网络接口调用等,对资源管理的集合就可以成为进程
4.线程:是操作系统最小的调度单位,是一串指令的集合
5.进程 要操作cpu,必须要创建一个线程~
大白话解释:
1.电脑有固定的内存,我们可以吧应用程序理解成进程,当我们打开各种各样的应用程序的时候,我们的内存就会越来越小,这是因为进程调度内存空间,
2.不同进程占用不同的空间相互不进行干涉,可以理解成qq程序崩溃不会影响到word程序,线程在进程中,线程会跟cup进行联系调度,
3.如果qq进程中 一个线程崩溃,会导qq进程的崩溃~简单理解进程就是划分程序要用的内存,里面包含着一些线程,进程会跟cup进行运算的调度
~~~
>[success] # 简单的使用线程
>[danger] ##### 简单使用线程
* 不使用线程
~~~
1.当第一个countdown(10) 执行完后执行countdown(5),是一个串行效果
~~~
~~~
import time
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
countdown(10)
countdown(5)
打印结果:
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
T-minus 2
T-minus 1
~~~
* 使用线程
~~~
1.使用线程中有两个参数,Thread(target=, args= ),target是目标函数,args是目标函数参数,但是是元组形式
2.start 调用线程
3.这样就形成t1 和t2 并行执行
~~~
~~~
from threading import Thread
import time
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
t1 = Thread(target=countdown, args=(5,))
t2 = Thread(target=countdown, args=(2,))
t1.start()
t2.start()
打印结果:
T-minus 5
T-minus 2
T-minus 4
T-minus 1
T-minus 3
T-minus 2
T-minus 1
~~~
>[danger] ##### 构造一个线程的继承类
~~~
1.通过继承线程类,重写里面的run方法,线程类中的run方法用来执行线程方法
~~~
~~~
import threading
import time
class MyTreading(threading.Thread):
def __init__(self,n):
super(MyTreading,self).__init__()
self.n = n
def run(self):
print("多线程"+self.n)
t1 = MyTreading("t1")
t2 = MyTreading("t2")
t1.start()
t2.start()
~~~
>[danger] ##### 让类中的方法开启线程
~~~
class CountdownTask:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self, n):
while self._running and n > 0:
print('T-minus', n)
n -= 1
time.sleep(5)
c = CountdownTask()
t = Thread(target=c.run, args=(10,))
t.start()
// 线程中参数共享,所以会停止线程
c.terminate()
t.join()
~~~
>[danger] ##### 判断线程是否运行 --- is_alive
~~~
t = Thread(target=countdown, args=(5,))
if t.is_alive():
print('Still running')
else:
print('Completed')
~~~
>[danger] ##### 设置线程守护函数 --- daemon
~~~
// true 开启线程守护
t = Thread(target=countdown, args=(10,), daemon=True)
~~~
>[danger] ##### 计算线程运行时长 -- join
~~~
1.想知道线程时长就给知道两个概念 --- 主线程和子线程2
2.主线程和 子线程就像打游戏, 主线任务和支线任务,主线任务就是这个程序从头到尾执行一遍,支线任务就是你开启的线程
~~~
* 通过例子认识主线程和子线
~~~
代码测试run函数的运行时长
1.这段代码的打印结果是0.0010008811950683594
2.实际我们通过尝试推断这个代码运行时间应该时最后一个线程结束时间 5/10+0.1
3.为什么执行结果小于我们做的预期判断,是因为,这个打印结果的运行时间是,主线程
4.就像打游戏我们的主线任务就是从头跑到尾,所以这段代码实际有 5+1个线程
~~~
~~~
import threading
import time
def run(n,m):
print("线程%s"%n)
time.sleep(m)
star_time = time.time()
# 开启五个线程,每个线程运行时间成递增
for i in range(5):
t1 = threading.Thread(target=run,args=(i,i/10+0.1) )
t1.start()
print('主线程')
print(float(time.time()-star_time))
~~~
* 计算线程时间运行时间 join
~~~
1.将线程连接知道最后一个线程结束才释放,也就是线程没有全部结束就不能往下执行
2.下面的案例只要子线程中第五个没结束,代码就不能往下进行,所以主线程等所有子线程结束后,在执行
~~~
~~~
import threading
import time
#创建一个保存线程的列表
list_threading = []
def run(n,m):
print("线程%s"%n)
time.sleep(m)
star_time = time.time()
for i in range(5):
t1 = threading.Thread(target=run,args=(i,i/10+0.1) )
t1.start()
list_threading.append(t1)
#循环列表执行join
for ii in list_threading:
ii.join()
print('主线程',star_time-time.time())
打印结果:
线程0
线程1
线程2
线程3
线程4
主线程 -0.5024936199188232
~~~
>[danger] ##### 打印子线程 和主线程
~~~
import threading
def run(n):
print("线程%s"%n,threading.current_thread())
for i in range(5):
t1 = threading.Thread(target=run ,args=(i,))
t1.start()
#主线程
print(threading.current_thread())
打印结果:
线程0 <Thread(Thread-1, started 9572)>
线程1 <Thread(Thread-2, started 7916)>
线程2 <Thread(Thread-3, started 4856)>
线程3 <Thread(Thread-4, started 5396)>
线程4 <Thread(Thread-5, started 9400)>
<_MainThread(MainThread, started 3360)>
~~~
>[danger] ##### 线程守护 --- daemon
~~~
1.当主线程结束后,开启守护的线程自动结束
2.通过运行结果发现因为是个主线程开启了守护,所以主线程结束其他线程也跟着结束
3.守护线程的生命周期在非守护线程结束时结束
~~~
* 未开启守护线程
~~~
1.下面线程主线程结束了下面线程依旧还在执行
~~~
~~~
import threading
import time
def run(n):
print("线程%s"%n)
time.sleep(2)
print("未开启守护打印线程%s"%n)
for i in range(4):
t1= threading.Thread(target=run,args=(i,), )
t1.start()
print("主线程")
打印结果:
线程0
线程1
线程2
线程3
主线程
未开启守护打印线程3
未开启守护打印线程2
未开启守护打印线程0
未开启守护打印线程1
~~~
* 开启守护线程 --- daemon
~~~
import threading
import time
def run(n):
print("线程%s"%n)
time.sleep(2)
print("未开启守护打印线程%s"%n)
for i in range(4):
t1= threading.Thread(target=run,args=(i,), daemon=True)
t1.start()
print("主线程")
打印结果:
线程0
线程1
线程2
线程3
主线程
~~~
- PYTHON-- 基础
- Python -- 变量、常量、注解
- 算数\比较\赋值\逻辑运算符
- Python -- input 控制台用户输入
- Python -- 流程控制/循环语句
- Python -- 切片
- Python -- 数据类型
- 基础数据类型
- int -- 数字类型
- str -- 字符类型
- bool -- 布尔类型
- list -- 列表
- type -- 元祖
- dict -- 字典
- set -- 集合
- Python -- 深浅copy
- Python -- 文件的读写
- Python -- 函数
- 函数 -- 做参数使用
- 函数 -- 闭包
- 函数 -- 生成器
- 函数 -- 列表推导式
- 案例
- 基础案例一
- 基础案例二
- 基础案例三
- COOKBOOK
- LIST、STR、DICT、TUPLE
- LIST - 列表方法总结
- 一、序列拆分成单独变量
- 二、* 妙用
- 三、deque- 双向队列
- 四、求找到最大或最小的N个元素
- 4.1 heapq-- 简单使用
- 五、去重并保持列表顺序不变
- 六、切片slice
- 七、counter 统计序列中元素次数
- 八、itemgetter 列表套着字典排序
- 九、处理大量的列表数据
- 十、随机事件处理列表
- DICT - 字典的总结方法
- 一、defaultdict 解决 KeyError
- 二、OrdereDict有序字典
- 三、zip 和 max/min 比较
- IDCT和LIST- 推导式
- 一、LIST 推导式
- 二、字典推到式
- TUPLE-元组
- 一、命名元组
- STR-字符串
- 一、常见的字符串方法
- 二、字符串拆分
- 三、字符串的位置匹配
- 四、字符串替换
- 五、正则大小写/换行匹配
- 六、对字节类型处理
- 数字、日期、时间处理
- 一、数字的处理
- 二、时间换算
- 2.1 时间运算
- 2.2计算某一时刻上周几的日期
- 2.2对时间转换格式优化
- 迭代器和生成器
- 一、iter 迭代器 使用案例
- 二、生成器 yeild
- 三、构建一个反向迭代方法
- 四、实现反正函数构造
- 五、迭代对象切片/跳过元素
- 六、迭代出所有的组合排列
- 七、索引-值迭代序列化
- 八、zip 同时迭代多个序列
- 九、同时循环多个可迭代对象
- 十、yield from 递归案例
- 十一、合并序列,并按顺序输出
- 十二、使用 iter 替代 while True
- 操作文件
- 一、处理文件路径
- 二、检测文件/获取文件信息
- 函数
- 一、函数基本案例使用
- 二、匿名函数
- 三、回调函数
- 四、闭包实现一个单个方法类
- 五、函数嵌套回调函数
- 类与对象
- 一、str/repr--让类字符串表示
- 二、format -- 格式化类的内容
- 三、with -- 上下文管理类
- 四、创建节省内存的类
- 五、将类里面方法变成属性
- 六、调用父类方法
- 七、扩展子类中的属性
- 八、创建新的类或者实类属性
- 九、简化数据结果,简化init
- 十、python 接口写法
- 十一、通过类属性创建委托访问
- 十二、__new__重新初始化init
- 十三、通过字符串调用类
- 元编程
- 一、装饰器
- 1.1 去掉装饰器修饰
- 1.2 可接受参数装饰器
- 1.3利用装饰器对函数参数类型检查
- 1.4编写类装饰器
- 1.5为类方法和静态方法加装饰器
- 1.6通过装饰器给装饰函数加参数
- 线程和进程