一、基本概念

程序: 指令集,静态,

进程: 当程序运行时,会创建进程,是操作系统资源分配的基本单位

线程: 进程的基本执行单元,每个进程至少包含一个线程,是任务调度和执行的基本单位

> 进程和线程之间的关系:

① 一个线程只属于一个进程
② 一个进程可以包含多个线程,只有一个主线程

>  进程和线程资源对比

① 进程具有独立的空间和系统资源

② 线程不具有独立的空间和系统资源

③ 同一个进程下的多个线程共享该进程的空间和系统资源

④ 局部变量不共享

> 多线程中对于贡献资源修改的问题 
--- 多线程的同步问题、 线程不安全、通过同步解决

二、 多线程

1.需要清楚的一点

  单核CPU: 宏观并行,微观实际上是串行 - 并发
  多核CPU: 微观本质并行

2.应用场合:  

  ① 计算密集型  --- 不适合单核CPU多线程  --- 数值计算
  ② I/O密集型  --- 适合单核CPU多线程   --- 频繁读写

3.优点:

   速度快

4.缺点:

  (1) 线程本身也是程序,线程越多,占用的内存越多;
  (2) 多线程的调用需要协调管理,CPU对线程的跟踪需要消耗内存;
  (3) CPU多线程的切换需要消耗内存
  (4) 多线程之间对共享资源问题,需要解决数据的一致性

三、 线程的创建

三种方式:

(1) threading模块
--- 通过指定target(函数名)和args(函数参数)
(2) 使用Thread类,重写run方法
(3) 使用线程池

3.1 threading模块

  1. import threading
  2. import time
  3. def misson(*args):
  4. for i in range(args[1]):
  5. print(i)
  6. time.sleep(1)
  7. # 创建线程对象,参数必须使用元组传递
  8. t = threading.Thread(target = mission, args = args)
  9. # 激活线程(排队),等待CPU分配时间片来执行
  10. t.start()
  11. t.start()

3.2. 使用Thread类,重写run方法

--- 适用于需要创建很多个执行方法相同的线程对象时,用类方法

  1. class My_Thread(threading.Thread):
  2. def __init__(self, n1):
  3. self.n1 = n1
  4. super().__init__()
  5. # run方法是真正执行函数认为的方法
  6. def run(self):
  7. for i in range(self.end):
  8. print(i)
  9. t1 = My_Thread()
  10. t1.start(10)

3.3 线程池

线程池的使用threadpool较少,使用concurrent.futures下的 ThreadPoolExecutor 线程池

  1. from concurrent.futures import ThreadPoolExecutor
  2. import time
  3.  
  4. def sayhello(a):
  5. print("hello: " + a)
  6. time.sleep(2)
  7.  
  8. def main():
  9. seed = ["a", "b", "c"]
  10.  
  11. # 第一种方法submit
  12. with ThreadPoolExecutor(3) as executor:
  13. for each in seed:
  14. executor.submit(sayhello, each)
  15.  
  16. # 第二种方法map
  17. with ThreadPoolExecutor(3) as executor1:
  18. executor1.map(sayhello, seed)
  19.  
  20. if __name__ == '__main__':
  21. main()

四、 线程的生命周期

(1) 新建 --- 创建线程对象,没有执行能力
(2) 就绪 --- 调用start方法,把执行权利交给CPU
(3) 运行 --- 执行线程任务,获得CPU时间片在一个线程运行时,可能将时间片分配给其他线程
(4) 阻塞 --- 处于等待过程,CPU不给阻塞状态分配时间片
(5) 死亡 --- run方法执行完毕或者抛出没有捕获的异常

五、线程的同步

  --- 在同一个进程下,各个线程共享资源引起不安全,即对成员变量的操作进行共享

1.  抢票问题 - 锁

  1. import time
  2. import threading
  3.  
  4. ticket = 100
  5.  
  6. def buy_ticket():
  7. global ticket
  8. while ticket:
  9. t = threading.current_thread()
  10. print(f'{t.name}{ticket}')
  11. time.sleep(0.5)
  12. ticket -= 1
  13.  
  14. if __name__ == '__main__':
  15. t1 = threading.Thread(target=buy_ticket)
  16. t1.name = '张三' # 设定线程名字
  17. t1.start()
  18. t2 = threading.Thread(target=buy_ticket)
  19. t2.name = '张四'
  20. t2.start()
  21. t3 = threading.Thread(target=buy_ticket)
  22. t3.name = '张五'
  23. t3.start()

运行结果如下,会出现重复的抢票,即多个线程获得同一个变量:

解决办法:

使用线程锁, 即在同一时间内,一个共享资源只能被一个线程访问

加锁      --- threading.Lock()
抢锁     --- lock.acquare()
解锁     --- lock.release()

  1. import time
  2. import threading
  3.  
  4. lock = threading.Lock()
  5. ticket = 100
  6. def buy_ticket():
  7. global ticket
  8. while True:
  9. try:
  10. lock.acquire()
  11. if ticket > 0:
  12. t = threading.current_thread()
  13. time.sleep(0.2)
  14. print(f'{t.name}抢到了第{ticket}张票')
  15. ticket -= 1
  16. else:
  17. break
  18. finally:
  19. lock.release()
  20.  
  21. t1=threading.Thread(target=buy_ticket)
  22. t1.name="张三"
  23. t2=threading.Thread(target=buy_ticket)
  24. t2.name="李四"
  25. t3=threading.Thread(target=buy_ticket)
  26. t3.name="王五"
  27.  
  28. t1.start()
  29. t2.start()
  30. t3.start()

2. 生产者消费者模型

(1)  消费者一直消费,商品=0,等待生产                    --- wait 
   (2)  生产者隔一段时间看一次,如果小于3,开始生产 --- 耗费CPU
   (3)  只要消费者消费了产品,通知生产者生产商品       --- notify

程序见Python并发复习2 - threading模块

六、多进程

1. 进程创建

(1)使用multiprocessing.Process(target=函数名)

(2)继承Process重写run

2.
进程操作

Os.getpid      # 得到本身进程id

Os.getppid    # 得到父进程id

Fork:复制进程,只能在linux下使用

其他方法同线程

3.
进程队列

进程优于线程:

不存在资源共享问题,没有同步锁,也没有死锁

多进程需要处理资源共享问题,使用队列序列化处理(进程队列已经处理好)

程序见Python并发复习2 - threading模块

Python并发复习1 - 多线程的更多相关文章

  1. Python并发复习2 - 多线程模块threading

    一.多线程的调用 threading 模块建立在thread 模块之上.thread模块以低级.原始的方式来处理和控制线程,而threading 模块通过对thread进行二次封装, 提供了更方便的a ...

  2. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  3. python并发编程之多线程基础知识点

    1.线程理论知识 概念:指的是一条流水线的工作过程的总称,是一个抽象的概念,是CPU基本执行单位. 进程和线程之间的区别: 1. 进程仅仅是一个资源单位,其中包含程序运行所需的资源,而线程就相当于车间 ...

  4. Python并发编程之多线程使用

    目录 一 开启线程的两种方式 二 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别 三 练习 四 线程相关的其他方法 五 守护线程 六 Python GIL(Global Interpret ...

  5. python并发编程之多线程1

    一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1.创建线程的开销比创建进程的开销小, ...

  6. python并发编程之多线程2------------死锁与递归锁,信号量等

    一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...

  7. Python并发复习3 - 多进程模块 multiprocessing

    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用的多进程包multiprocessing,只需要定 ...

  8. python 并发编程之多线程

    一.线程理论 1.什么是线程 ​ 多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源. 所以,进程只是用来把资 ...

  9. python并发编程之多线程2---(死锁与递归锁,信号量等)

    一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...

随机推荐

  1. web的分页方法

    web分页的三种方式,闲来无事总结一下. 1.使用前端表格插件进行分页 例如用bootstrap的拓展table组件,注意设置其分页属性时设置为"client", 即是 sideP ...

  2. redis持久化之AOF

    一:Redis的AOF是什么? 以日志的形式来记录每个写操作(读操作不记录),将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构 ...

  3. Op-level的快速算法

    十岁的小男孩 本文为终端移植的一个小章节. 目录 引言 FFT Conv2d (7x7, 9x9) Winograd Conv2d (3x3, 5x5) 引言 本节针对CNN进行加速计算的,主要有以下 ...

  4. laravel zh-CN

    位置: 调用:

  5. kali linux 更新问题

    1.使用一次更新和升级软件替换 apt-get install && apt -y full -upgrade 之后使用 reboot重启    系统,重启之后 再次使用命令   ap ...

  6. JS实现继承的几种方式(转)

    转自:幻天芒的博客 前言 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一.那么如何在JS中实现继承呢?让我们拭目以待. JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如 ...

  7. js 浮点数相加 变成字符串 解决方案

    var count = 0; count+=Number(parseFloat(value[i]['sla']).toFixed(2)); 数字相加的时候最好使用Number转换一下

  8. 步步为营103-ZTree 二级联动

    1:添加引用 <%--流程类别多选--引用js和css文件--开始--%> <link rel="stylesheet" href="../css/zT ...

  9. jQuery EasyUI一个基于 jQuery 的框架(创建网页所需的一切)

    jQuery EasyUI学习网址:http://www.runoob.com/jeasyui/jqueryeasyui-tutorial.html jQuery MiniUI学习网址:http:// ...

  10. ASP.NET Core Middleware管道介绍

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Use(async (context, ne ...