线程和进程

1. 同步和异步

针对结果

  • 同步 - 多任务,多个任务执行的时候有先后的顺序, 必须一个先执行后, 另外一个才能继续执行, 只有一条运行主线

  • 异步 - 多任务, 多个任务之间执行没有想先后顺序, 可以同时运行, 执行时先后顺序不会对程序有什么影响, 存在多条运行主线

2. 阻塞和非阻塞

针对运行状态 线程的状态(就绪、运行、阻塞)

  • 阻塞 - 从调用者的角度出发, 如果在调用的时候, 被卡住, 不能再继续往下执行, 需要等待, 就是 阻塞

  • 非阻塞 - 从调用者的角度出发, 如果在调用的时候, 没有被卡住, 能够继续向下执行, 无需等待, 就是 非阻塞

3. 并发和并行

  • 并发 - 同时进行

  • 并行 - 切换处理, 类似线程之间不断切换

下面这篇文章可以参考

https://blog.csdn.net/timemachine119/article/details/54091323

进程和线程使用

  • 进程:内存独立, 线程共享同一进程的内存, 一个进程就像是一个应用程序(app)

  • 进程是资源的组合, 线程是执行的单位

  • 进程之间不能直接相互访问, 同一进程中的线程可以相互通讯

  • 创建新的进程很消耗系统资源, 线程非常轻量, 只需要保存线程运行时的必要数据, 如上下文, 程序的堆栈信息

  • 同一进程里的线程可以相互控制, 父进程可以控制子进程

开多进程

  • redis 缓存问题 读写分离, 单独设置缓存服务器来保存缓存, 读写都在该服务器上进行

关于 IO 密集型任务 和 计算密集型任务

  • CPU密集型 - 多进程 计算

  • IO密集型 - 多线程 文本操作

如果多线程的进程是CPU密集型的,那多线程并不能有多少效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降,推荐使用多进程;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。所以我们根据实验对比不同场景的效率

线程常用方法

  ​t.start() 激活线程  (开始)t.getName()  获取线程名称t.setName()  设置t.name : 获取或设置线程的名称​t.is_alive() : 判断线程是否为激活状态​t.isAlive() :判断线程是否为激活状态​t.setDaemon() 设置为后台线程或前台线程(默认:False);通过一个布尔值设置线程是否为守护线程,必须在执行start()方法之后才可以使用。如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止;如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止​t.isDaemon() : 判断是否为守护线程​t.ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None。​t.join() :逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义​t.run() :线程被cpu调度后自动执行线程对象的run方法

进程

  ​​import osimport timeimport random​from multiprocessing import Process​​def coding():while True:print('AAAAAA, 进程号:%s' % os.getpid())time.sleep(random.randint(1, 5))print('BBBBBBB, 进程号:%s' % os.getpid())​​def play():while True:print('1111111111, 进程号:%s' % os.getpid())time.sleep(random.randint(1, 5))print('2222222222, 进程号:%s' % os.getpid())​​def main():p1 = Process(target=coding)p2 = Process(target=play)p1.start()   # 进程之间在不阻塞的情况下是没有影响的,# 阻塞   等执行完才会进行下一个# p1.join()# p2.join(timeout=3)  # 设置超时时间​p2.start()​​if __name__ == '__main__':main()​​

线程

  ​​​import threadingimport time​​class Study(threading.Thread):​def __init__(self, name):super(Study, self).__init__()self.s_name = name​def run(self):  # 重构方法print('当前线程名称- %s' % threading.current_thread().name)print('开始学习!- %s' % self.s_name)time.sleep(3)print('学习结束')print('当前线程名称- %s' % threading.current_thread().name)# print('---' * 20)​​def main():s1 = Study('语文')s2 = Study('数学')# 守护线程  在 start 前  主线程结束 子线程会被强制结束# s1.daemon = True# s2.daemon = True# s1.start()# 阻塞# s1.join()  # 阻塞在这里  等 s1 结束 再向下执行程序# s2.start()s1.run()   # 都变为主线程  程序会顺序执行, 不存在同时执行s2.run()   # 相当于只是在执行函数, 并没有使用 多线程print('测试结束-----')# s1.run()​​if __name__ == '__main__':main() ​
  • 线程锁

多线程会共享资源, 需要线程锁, 当多个线程需要对同一资源进行修改时, 需要线程锁来保护资源, 避免操作资源出错

未加锁

  ​​import threading​​class MyThread(threading.Thread):​def __init__(self):super(MyThread, self).__init__()# self.s_name = s_name​def run(self):global nprint('number: %s,  threading name: %s'% (n, self.name))n += 1​​def main():thread_list = []for i in range(20):t1 = MyThread()thread_list.append(t1)​for t in thread_list:t.start()​​if __name__ == '__main__':n = 0main()

加线程锁

  • Lock() 和 RLock()

  • lock = threading.RLock() 允许加多把锁

  • lock = threading.Lock() 只能加一把锁

  • lock = threading.BoundedSemaphore(3) 同时允许三个线程进入, 同时进入的线程多于 3 时会引发 ValueError

锁的本质是内部有一个计数器,调用 acquire() 会使这个计数器 -1,release() 则是+1.计数器的值永远不会小于 0,当计数器到 0 时,再调用 acquire() 就会阻塞,直到其他线程来调用release()

  ​​import threading​​mylock = threading.Lock()  # 添加锁​​class MyThread(threading.Thread):​def __init__(self):super(MyThread, self).__init__()# self.s_name = s_name​def run(self):if mylock.acquire():  # 锁定global nprint('number: %s,  threading name: %s'% (n, self.name))n += 1mylock.release()  #释放锁​​def main():thread_list = []for i in range(20):t1 = MyThread()thread_list.append(t1)​for t in thread_list:t.start()​​if __name__ == '__main__':n = 0main()​

事件Event

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

  • clear:将“Flag”设置为False

  • set:将“Flag”设置为True

  • Event.isSet() :判断标识位是否为Ture

  1 # 事件 event2 lock = threading.Event()3 def task(arg):4     time.sleep(1)5     # 锁住所有的线程6     lock.wait()7     print(arg)8 for i in range(10):9     t = threading.Thread(target=task,args=(i,))10     t.start()11 while 1:12     value = input('>>:').strip()13     if value == '1':14         lock.set() # 打开锁,执行上面的print15         # lock.clear() # 再锁上

线程池

  • 会让线程 更具线程池设置的个数进行 执行, 每次同时执行的个数是设置的个数

  ​import time​from concurrent.futures import ThreadPoolExecutor​def task(i):​time.sleep(2)print('hello!, 编号:', i)​pool = ThreadPoolExecutor(3)​for i in range(50):pool.submit(task, i)   # 每次输出 三个 hello​

线程池的回调函数

  • 将前面函数的返回值作为后面的结果进行传递

  • future.add_done_callback(add1000)

  • num = future.result()

  ​import time​from concurrent.futures import ThreadPoolExecutor​​def add100(num):print('我是 100 ')return num + 100​​def add1000(future):print('我是 + 1000')num = future.result()time.sleep(5)print(num + 1000)​​def main():pool = ThreadPoolExecutor(3)for num in range(1,50):print('开始计算数字:%s !' % num)future = pool.submit(add100, num)future.add_done_callback(add1000)  # 前面的结果返回后进行下个函数的调用​​if __name__ == '__main__':main()

多进程

  • 多进程之间可以数据共享

  ​import time​from multiprocessing import Process​​def task():time.sleep(1)print('hello!')​​def main():​for i in range(10):p = Process(target=task)# p.daemon = Truep.start()# p.join()print('主进程结束!!!')​​if __name__ == '__main__':main()###  数据共享​import time​from multiprocessing import Process, Array​​def task(num, li):time.sleep(1)li[num] = numprint(list(li))​​def main():li = Array('i', 10)for i in range(10):p = Process(target=task, args=(i, li))# p.daemon = Truep.start()# p.join()print('主进程结束!!!')​​if __name__ == '__main__':main()

进程池

和线程池差不多

  from concurrent.futures import ProcessPoolExecutor as PPE #基本用法def task(arg):time.sleep(1)print(arg) pool = PPE(5)for i in range(10):pool.submit(task,i) # 进程池回调def call(arg):data = arg.result()print(data) def task(arg):print(arg)return arg+100 pool = PPE(5)for i in range(10):obj = pool.submit(task,i)obj.add_done_callback(call)

Python- 线程和进程相关推荐

  1. Python 线程和进程和协程总结

    Python 线程和进程和协程总结 线程和进程和协程 进程 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间.内存等)的基本单位: 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其 ...

  2. Python|线程和进程|阻塞|非阻塞|同步|异步|生成器和协程|资源竞争|进程间通信|aiohttp库|daemon属性值详解|语言基础50课:学习(11)

    文章目录 系列目录 原项目地址 第34课:Python中的并发编程-1 线程和进程 多线程编程 使用 Thread 类创建线程对象 继承 Thread 类自定义线程 使用线程池 守护线程 资源竞争 G ...

  3. python线程和进程-未完待续

    python线程和进程-未完待续 环境变量 0. 概念 1. 并行/并发 并行 并发 并行与并发的关系 2.进程/线程 基本概念 线程 多线程 队列 互斥锁/线程共享 阻塞 锁 条件锁 进程 多进程 ...

  4. Python线程、进程知识整理

    一.python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 im ...

  5. python线程与进程视频教程_[PYTHON系列教程]→进程 vs. 线程

    我们介绍了多进程和多线程,这是实现多任务最常用的两种方式.现在,我们来讨论一下这两种方式的优缺点.首先,要实现多任务,通常我们会设计Master-Worker模式,Master负责分配任务,Work ...

  6. python线程与进程

    建议用pycharm阅读,可以收缩,也可以测试 '''IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.目 ...

  7. Python线程、进程、进程池、协程

    Python线程,切记Python的GIL特性 import threadingdef func():print(threading.current_thread().getName())passcl ...

  8. 【转载】Python线程、进程和协程详解

    从操作系统角度 操作系统处理任务,调度单位是进程和线程. 进程:表示一个程序的执行活动(打开程序.读写程序数据.关闭程序) 线程:执行某个程序时,该进程调度的最小执行单位(执行功能1,执行功能2) 一 ...

  9. Python线程和进程的了解,多线程多进程

    锁:好处是确保某段关键代码只能由一个线程从头到尾的完整执行     坏处是有:阻止了多线程并发执行,包含锁的某段代码实际上只是以单线程模式运行,效率大大下降,其次,由于存在多个锁,不同的线程持有不同的 ...

  10. python线程、进程、协程

    进程与线程之间的定义 计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. 程序是 ...

最新文章

  1. WPF查找子控件和父控件方法
  2. C语言易错图形题--打印n行n列的空心正方形图案
  3. php实现cookie加密解密
  4. 第8集析构函数中抛出的异常
  5. BeetleX使用bootstrap5开发SPA应用
  6. 解决: java.net.ConnectException: Connection refused: connect
  7. [导入]ASP.NET 配置节架构
  8. 多程序同时操作 mysql_关于多个程序同时操作一个表发生死锁的问题
  9. 技术规范,过几天发个压缩包,一次下载全部拥有
  10. 配色三部曲-你真懂这些色彩术语吗?
  11. 单片机/开发板连接配置的三种方式
  12. 个人公众号注销方法_微信公众号注销后怎么申请 恢复公众号的方法步骤
  13. java excel 饼图_Java 在 Excel 中创建饼图/环形图
  14. excel怎么设置打印区域_Excel如何设置打印区域及打印区域如何调整
  15. 融合DE 端和FE端数据,利用小波变换生成时频图,再分别利用DCNN、KNN和DNN进行对比实验(python代码)
  16. Android uevent进程源码分析
  17. 无法达成目标的五个关键因素
  18. 【系统之家首发】10月最新GhostWin7_SP1旗舰版(64位)电脑公司装机版v2011.10
  19. CSDN的积分如何获取
  20. Android音频和视频开发

热门文章

  1. IM即时通讯开发群聊消息的已读回执功能该怎么实现?
  2. 华东政法大学教学管理系统_华东政法大学教学管理系统(华政研究生管理信息系统)...
  3. 【git-02】用git管理vue项目
  4. Python:读出文本本件,统计单词数输出;读出文本文件,随机输出其中的10个单词
  5. 《京韵大鼓——大西厢》(骆玉笙)(唱词文本)
  6. 裁剪任意直线段 liang-barshky算法 c
  7. Dubbo的负载均衡
  8. 苹果电脑黑屏后重装系统的方法,可以保护所有数据,不使用u盘和移动硬盘
  9. SAP 银企直连付款流程
  10. [创业-19]:财务报表 - 所有者权益之实收资本