一,线程与进程之间的关系:(从知乎上看到的)

一个必须知道的事实:执行一段程序代码,实现一个功能的过程介绍 ,当得到CPU的时候,相关的资源必须也已经就位,就是显卡啊,GPS啊什么的必须就位,然后CPU开始执行。这里除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的程序上下文。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去的最后一步工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存。

串联起来的事实:前面讲过在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。。。

========= 重要的东西出现了========
进程和线程就是这样的背景出来的,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。

  • 进程就是包换上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文

线程是什么呢?
进程的颗粒度太大,每次都要有上下的调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。那么这里具体的执行就可能变成:

程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。

这里a,b,c的执行是共享了A的上下文,CPU在执行的时候没有进行上下文切换的。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。

到此全文结束,再一个总结:

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同,一个进程中包含了多个线程,在一个时间段内,只能有一个线程占用cpu,cpu不能同时执行多个任务,只不过cpu运行速度太快,我们感知不到,就以为,线程可以同时执行,对于多核cpu,实际也同一个时间段也只有一个cpu在工作

 
二,多线程,使用threading模块
一个简单的多线程
 
import threading

import time

def axb(name):
time.sleep(1)
print(name)
for i in range(10):
t=threading.Thread(target=axb,args=(i,)) ##args 定义的是一个元组,必须加逗号,才能识别为元组
t.start() print('game over')

三,线程等待

线程等待,多线程在运行的时候,每个线程都是独立运行的,不受其他的线程干扰,如果想在哪个线程运行完之后,再做其他操作的话,就得等待它完成,那怎么等待呢,使用join,等待线程结束


import threading
import time
def run():
print('qqq')
time.sleep(1)
print('done!')
lis = []
for i in range(5):
t = threading.Thread(target=run)
lis.append(t)
t.start()
for t in lis:
t.join() #主线程等待子线程执行完
print('over')
 

四,获取多线程时执行结果的返回值

例如我们做接口测试时候,需要获取每个线程执行时间

import threading
import time
import requests
run_times = []
#怎么获取到多线程执行的函数里面的返回值
def blog():
stat_time = time.time()
r = requests.get('http://www.nnzhp.cn/').text
end_time = time.time()
run_time = end_time-stat_time
run_times.append(run_time)
objs = []
for i in range(100):
t = threading.Thread(target=blog())
t.start()
objs.append(t)
for obj in objs:
obj.join()#join中可以设置timeout时间,主线程等待时间超过timeout时间后就会继续执行,不再等待
avg = sum(run_times)/len(run_times)
print('平均响应时间是',avg)

五,守护线程:就相当于你是一个国王(非守护线程),然后你有很多仆人(守护线程),这些仆人都是为你服务的,一但你死了,那么你的仆人都给你陪葬。

主线程死掉了(执行完了),那么不管子线程运行完否,都一起结束
import time
import threading def test():
time.sleep(2)
print('hhhh')
for i in range(5):
t=threading.Thread(target=test)
t.setDaemon(True)#设置子线程为守护线程
t.start()

程序执行结果不会打印 hhhh,因为主线程执行完的时候,子线程还没执行完,所以,主线程死掉了,守护子线程跟着消亡了

六、锁:线程锁就是,很多线程一起在操作一个数据的时候,可能会有问题,就要把这个数据加个锁,同一时间只能有一个线程操作这个数据。

import threading
from threading import Lock num = 0
lock = Lock() # 申请一把锁 def run():
global num
lock.acquire() # 加锁
num += 1
lock.release() # 解锁 lis = []
for i in range(5):
t = threading.Thread(target=run)
t.start()
lis.append(t)
for t in lis:
t.join()
print('over', num)

七,多进程:Python里面的多线程,是不能利用多核CPU的,如果想利用多核CPU的话,就得使用多进程,python中多进程使用multiprocessing模块。

from  multiprocessing  import Process
import time def test(i):
time.sleep(1)
print(i) if __name__=='__main__':
for i in range(10):
p=Process(target=test,args=(i,))
p.start()

threading与实例对象提供了几个方法可以让我们更直观的学习线程。

threading.active_count()  # 返回当前运行的线程个数

threading.enumerate()  # 返回当前运行中的线程list

threading.current_thread()  # 返回当前的线程变量

t1.start()  # 启动线程

t1.is_alive()  # 判断线程是否在运行 运行指启动后、终止前。

t1.getName()  # 获取线程名

t1.setName('填写更改后的名称')  # 对线程进行命名

t1.setDaemon(True)  # 设置守护线程

t1.isDaemon()  # 判断是否是守护线程

t1.join(timeout=20)  # 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)

最新文章

  1. php-设置关键词高亮的字符串处理函数
  2. jsp页面动态显示时间
  3. requests高级用法
  4. halcon三种模板匹配方法
  5. SQL更改表字段为自增标识
  6. java前后台之间传值的几种方式
  7. [zz] 英文大写缩写前要加THE吗
  8. Zookeeper集群安装详解
  9. c语言函数注意点
  10. SQL SERVER 执行大于80M的SQL 脚本
  11. SQL练习题完整(做完你就是高手)
  12. MATLAB 2012b license checkout failed
  13. Java中静态变量与实例变量
  14. spring整合thymeleaf
  15. day70 cookie & session 前后端交互分页显示
  16. vue cli3.0 结合echarts3.0和地图的使用方法
  17. How to trigger a Kubernetes cronjob manually-手动触发一个cronjob
  18. Android开发 ---Media
  19. Android安全系列之:如何在native层保存关键信息
  20. maven 使用记录之修改 maven默认jdk版本

热门文章

  1. Markdown GUI编辑器推荐 windows mac
  2. sql exist 优化查询时间
  3. Oracle中NVL、NVL2、NULLIF 三个函数的区别?
  4. Linux中crontab下scp文件传输的两种方式
  5. Mysql字符串截取函数
  6. Mysql 行数据转换为列数据
  7. 【BZOJ3769】spoj 8549 BST again DP(记忆化搜索?)
  8. 【BZOJ4177】Mike的农场 最小割
  9. What Every Computer Scientist Should Know About Floating-Point Arithmetic
  10. html5 (新一代的html)