一.并发和并行

  1. 多任务:一定时间段内,充分利用cpu资源,同时去执行多个任务

  2. 并发: 快速交替的 去执行多任务

  3. 并行: 真正同时的 去执行多任务 ,就是同时进行

二.多进程

1.多进程入门

知识点:

  1. 进程含义: 运行中的程序

  2. 进程特点: cpu资源分配的 最小单位

  3. 多进程模块: multiprocessing

  4. 进程类: Process

使用步骤:

  1. 导包 : import multiprocessing

  2. 创建对象 : 子进程对象 = multiprocessing.Process(target=任务名)

  3. 开启进程 : 子进程对象.start()

示例:

import multiprocessing
import time
# 任务1
def dance():for i in range(5):time.sleep(0.1)print('跳舞',i)
# 任务2
def sing():for i in range(5):time.sleep(0.3)print('唱歌',i)
# 多进程放到main内
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=dance)p2 = multiprocessing.Process(target=sing)# 2.开启进程p1.start()p2.start()

2.os模块获取进程编号

知识点:

获取当前进程id: os.getpid()   pid: processing id获取父进程id: os.getppid()   ppid: parent processing id

示例:

import multiprocessing
import os
import time
# 任务1
def dance():print('dance子进程:', os.getpid(), os.getppid())for i in range(5):time.sleep(0.1)print('跳舞',i)
# 任务2
def sing():print('sing子进程:', os.getpid(),os.getppid())for i in range(5):time.sleep(0.3)print('唱歌',i)
# 多进程放到main内
if __name__ == '__main__':print('main主进程:',os.getpid())# 1.创建进程对象p1 = multiprocessing.Process(target=dance)p2 = multiprocessing.Process(target=sing)# 2.开启进程p1.start()p2.start()

3.Process()类的传参,2种方式

知识点:

  • args: 以元组方式传参 注意:如果只有一个参数需要加逗号, 如果多个参数顺序要任务参数顺序一致

  • kwargs: 以字典方式传参 注意:需要{k:v}形式传参,k必须和任务的形参名一致

示例:

import multiprocessing
import os
import time
# 任务1
def dance(num):print('dance子进程:', os.getpid(), os.getppid())for i in range(num):time.sleep(0.1)print('跳舞',i)
# 任务2
def sing(num):print('sing子进程:', os.getpid(), os.getppid())for i in range(num):time.sleep(0.3)print('唱歌',i)
# 多进程放到main内
if __name__ == '__main__':print('main主进程:', os.getpid())# 1.创建进程对象p1 = multiprocessing.Process(target=dance,args=(5,))p2 = multiprocessing.Process(target=sing,kwargs={'num':5})# 2.开启进程p1.start()p2.start()

4.获取当前进程信息

知识点:

  1. 获取当前进程对象: multiprocessing.current_process()

  2. 获取当前进程name: multiprocessing.current_process().name

  3. 获取当前进程pid: multiprocessing.current_process().pid

示例:

import multiprocessing
# 任务1
def dance():print('dance子进程对象:', multiprocessing.current_process())print('dance子进程name:', multiprocessing.current_process().name)print('dance子进程id:', multiprocessing.current_process().pid)# 任务2
def sing():print('sing子进程对象:', multiprocessing.current_process())print('sing子进程name:', multiprocessing.current_process().name)print('sing子进程id:', multiprocessing.current_process().pid)# 多进程放到main内
if __name__ == '__main__':print('main主进程对象:', multiprocessing.current_process())print('main主进程name:', multiprocessing.current_process().name)print('main主进程id:', multiprocessing.current_process().pid)# 1.创建进程对象p1 = multiprocessing.Process(target=dance,name='danceProcess')p2 = multiprocessing.Process(target=sing,name='singProcess')# 2.开启进程p1.start()p2.start()

5.注意事项

1. 多进程间不能共享全局变量:

import multiprocessingmylist = []
# 写
def write():global mylistmylist = [1,2,3,4,5]print('write:',mylist) # [1, 2, 3, 4, 5]
# 读
def read():global mylistprint('read:',mylist)  # []  说明多个进程间不共享全局变量# 多进程需要放到main内
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=write)p2 = multiprocessing.Process(target=read)# 2.开启进程p1.start()p2.start()

2. 主进程默认等待子进程结束再结束:

import multiprocessing
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=task)# 2.开启进程p1.start()# 3.主进程等待0.5秒time.sleep(0.5)print('主进程中最后一行代码....')

2. 主进程默认等待子进程结束再结束:

import multiprocessing
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=task)# 2.开启进程p1.start()# 3.主进程等待0.5秒time.sleep(0.5)print('主进程中最后一行代码....')

3. 多进程执行是无序的:

import multiprocessing
import time# 任务
def show():time.sleep(2)print(multiprocessing.current_process().name)
# 学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
# 多任务
if __name__ == '__main__':for _ in range(5):# 创建进程对象p = multiprocessing.Process(target=show)# 开启进程p.start()

6.设置子进程跟着主进程一起结束#

知识点:

方式1 设置子进程守护主进程:  子进程对象.daemon = True   注意: 需要在开启进程之前设置   :                          daemon/ˈdiːmən/守护进程方式2 手动销毁子进程     :  子进程对象.terminate()    terminate:结束,终止

1. 守护主进程:

import multiprocessing
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=task)# 方式1: 开启子进程之前设置守护主进程p1.daemon = True# 2.开启进程p1.start()# 3.主进程等待0.5秒time.sleep(0.5)print('主进程中最后一行代码....')

2. 手动销毁子进程:

import multiprocessing
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建进程对象p1 = multiprocessing.Process(target=task)# 2.开启进程p1.start()# 3.主进程等待0.5秒time.sleep(0.5)print('主进程中最后一行代码....')# 方式2: 手动销毁子进程p1.terminate()

三.多线程

1.多线程入门

知识点:

  1. 线程含义: 进程中 执行代码的 一个分支 (一个进程至少有一个线程)

  2. 线程作用: 线程是 cpu调度的 最小单位

  3. 多线程模块: threading

  4. 线程类: Thread

使用步骤:

  1. 导包 : import threading
  2. 创建对象 : 子线程对象 = threading.Thread(target=任务名)
  3. 开启进程 : 子线程对象.start()

示例:

import threading# 任务1
def dance():for i in range(5):print('跳舞',i)
# 任务2
def sing():for i in range(5):print('唱歌',i)# 多任务
if __name__ == '__main__':# 1.创建子线程对象t1 = threading.Thread(target=dance)t2 = threading.Thread(target=sing)# 2.开启线程t1.start()t2.start()

2.多线程的传参

知识点:

args: 以元组方式传参 注意:如果只有一个参数需要加逗号, 如果多个参数顺序要任务参数顺序一致

kwargs: 以字典方式传参 注意:需要{k:v}形式传参,k必须和任务的形参名一致

与多进程一模一样

示例:

import threading
"""
args: 以元组方式传参   注意:如果只有一个参数需要加逗号, 如果多个参数顺序要任务参数顺序一致
kwargs: 以字典方式传参  注意:需要{k:v}形式传参,k必须和任务的形参名一致
"""
# 任务1
def dance(num):for i in range(num):print('跳舞', i)# 任务2
def sing(num):for i in range(num):print('唱歌', i)# 多任务
if __name__ == '__main__':# 1.创建子线程对象t1 = threading.Thread(target=dance,args=(5,))t2 = threading.Thread(target=sing,kwargs={'num':5})# 2.开启线程t1.start()t2.start()

3.多线程注意事项

  1. 多线程是在一个进程中
import os
import threading
"""
args: 以元组方式传参   注意:如果只有一个参数需要加逗号, 如果多个参数顺序要任务参数顺序一致
kwargs: 以字典方式传参  注意:需要{k:v}形式传参,k必须和任务的形参名一致
"""
# 任务1
def dance(num):print(f'dance子线程中当前进程pid:{os.getpid()}')for i in range(num):print('跳舞', i)# 任务2
def sing(num):print(f'sing子线程中当前进程pid:{os.getpid()}')for i in range(num):print('唱歌', i)# 多任务
if __name__ == '__main__':print(f'main主线程中当前进程pid:{os.getpid()}')# 1.创建子线程对象t1 = threading.Thread(target=dance,args=(5,))t2 = threading.Thread(target=sing,kwargs={'num':5})# 2.开启线程t1.start()t2.start()

2. 多线程是可以共享全局变量

import threadingmylist = []
# 写
def write():global mylistmylist = [1,2,3,4,5]print('write:',mylist) # [1, 2, 3, 4, 5]
# 读
def read():global mylistprint('read:',mylist)  # [1, 2, 3, 4, 5] 访问到了write线程修改后的内容说明多线程共享全局变量if __name__ == '__main__':# 1.创建线程对象t1 = threading.Thread(target=write)t2 = threading.Thread(target=read)# 2.开启线程t1.start()t2.start()

3. 主线程默认等待子线程结束再结束

import threading
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建线程对象t = threading.Thread(target=task)# 2.开启线程t.start()# 3.为了效果明显点,主线程等待0.5秒time.sleep(0.5)print('主线程中最后一行代码....')

4. 多线程是无序的

import threading
import time# 任务
def show():time.sleep(1)print(threading.current_thread().name)# 多任务
if __name__ == '__main__':for _ in range(5):# 创建线程对象p = threading.Thread(target=show)# 开启线程p.start()

4.设置守护主线程

知识点:

方式1: daemon属性        t.daemon = True       daemon/ˈdiːmən/守护进程方式2: setDaemon()方法   t.setDaemon(True)

一个是属性,一个是方法,用哪个都可以

示例:

import threading
import time# 任务
def task():for i in range(10):print('任务进行中...')time.sleep(0.2)# 多任务
if __name__ == '__main__':# 1.创建线程对象t = threading.Thread(target=task)# 方式1: daemon属性# t.daemon = True# 方式2: setDaemon()方法t.setDaemon(True)# 2.开启线程t.start()# 3.为了效果明显点,主线程等待0.5秒time.sleep(0.5)print('主线程中最后一行代码....')

5.获取当前线程信息

知识点:

  1. 获取当前线程对象:threading.current_thread()

  2. 获取当前线程name:threading.current_thread().name

  3. 获取当前线程id:threading.current_thread().native_id

示例:

import threadingdef dance():print(f'dance当前线程对象:{threading.current_thread()}')print(f'dance当前线程name:{threading.current_thread().name}')print(f'dance当前线程id:{threading.current_thread().native_id}')def sing():print(f'sing当前线程对象:{threading.current_thread()}')print(f'sing当前线程name:{threading.current_thread().name}')print(f'sing当前线程id:{threading.current_thread().native_id}')if __name__ == '__main__':print(f'main当前线程对象:{threading.current_thread()}')print(f'main当前线程name:{threading.current_thread().name}')print(f'main当前线程id:{threading.current_thread().native_id}')# 1.创建线程对象t1 = threading.Thread(target=dance,name='DanceThread')t2 = threading.Thread(target=sing,name='SingThread')# 2.开启线程t1.start()t2.start()

6.线程安全问题

1. 出现的线程安全问题:

import threadingsum = 0def sum1():global sumfor i in range(1000000):sum += 1print(sum) # 1114834def sum2():global sumfor i in range(1000000):sum += 1print(sum)  # 1339347# 单任务不会出现问题 正常结果  1000000 2000000
# 多任务出现了问题
if __name__ == '__main__':# 1.创建线程对象t1 = threading.Thread(target=sum1)t2 = threading.Thread(target=sum2)# 2.开启线程t1.start()t2.start()

2. 锁机制解决线程安全问题:

import threadingsum = 0def sum1(lock):lock.acquire() # 加锁global sumfor i in range(1000000):sum += 1print(sum) # 1000000lock.release() # 释放锁def sum2(lock):lock.acquire()  # 加锁global sumfor i in range(1000000):sum += 1print(sum)  # 2000000lock.release()  # 释放锁# 单任务不会出现问题 正常结果  1000000 2000000
# 多任务出现了问题 ,利用锁机制解决问题
if __name__ == '__main__':# 创建一个锁,保证两个任务用的是同一个锁lock= threading.Lock()# 1.创建线程对象t1 = threading.Thread(target=sum1,args=(lock,))t2 = threading.Thread(target=sum2,args=(lock,))# 2.开启线程t1.start()t2.start()

3. join解决线程安全问题:

import threadingsum = 0def sum1():global sumfor i in range(1000000):sum += 1print(sum)  # 1000000def sum2():global sumfor i in range(1000000):sum += 1print(sum)  # 2000000
# 学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
# 单任务不会出现问题 正常结果  1000000 2000000
# 多任务出现了问题 ,利用join解决问题
if __name__ == '__main__':# 1.创建线程对象t1 = threading.Thread(target=sum1)t2 = threading.Thread(target=sum2)# 2.开启线程t1.start()t1.join()  # t1线程告诉其他线程等我执行完,你们其他线程再执行t2.start()

四.进程和线程对比

关系

  1. 线程是依附在进程里面的,没有进程就没有线程

  2. 一个进程默认提供一条线程,进程可以创建多个线程

区别

  1. 进程之间不共享全局变量
  2. 线程之间共享全局变量,但是要注意资源竞争的问题,解决办法是互斥锁或者线程同步
  3. 创建进程的资源开销要比创建线程的资源开销要大
  4. 进程是操作系统 资源分配 的基本单位,线程是 CPU调度 的基本单位
  5. 线程不能够独立执行,必须依存在进程中
  6. 多进程开发比单进程多线程开发稳定性要强

优缺点

进程优缺点:
优点:可以用多核
缺点:资源开销大

线程优缺点:
优点:资源开销小
缺点:不能使用多核

Python多任务教程相关推荐

  1. 大学python用什么教材-Python大学教程(普通高等教育十三五规划教材)

    导语 内容提要 吕云翔.赵天宇.张元编著的<Python大学教程>介绍了使用Python语言进行程序设计的方法及其应用. 全书共14章,分为三部分.第一部分为基础篇(第1-5章),主要介绍 ...

  2. python多线程教程_Python多线程编程教程【2小时学会】

    Python多线程编程教程[2小时学会] 中级共14课 从0开始学习python多任务编程,想了解python高并发实现,从基础到实践,通过知识点 + 案例教学法帮助你想你想迅速掌握python多任务 ...

  3. Python学习教程(Python学习路线):Day13-进程和线程

    Python学习教程(Python学习路线):进程和线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持"多任务"的操作系统,这使得我们可以同时运行多 ...

  4. Python是什么?Python基础教程400集大型视频,全套完整视频赠送给大家

    2020最新Python零基础到精通资料教材,干货分享,新基础Python教材,看这里,这里有你想要的所有资源哦,最强笔记,教你怎么入门提升!让你对自己更加有信心,重点是资料都是免费的,免费!!! 获 ...

  5. python编程教程第九讲_Python入门学习视频,最全面讲解视频无偿分享,这些基础知识你都懂了吗?...

    2020最新Python零基础到精通资料教材,干货分享,新基础Python教材,看这里,这里有你想要的所有资源哦,最强笔记,教你怎么入门提升!让你对自己更加有信心,重点是资料都是免费的,免费!!! 如 ...

  6. Python高级教程:玩转Linux操作系统

    Python高级教程:玩转Linux操作系统 操作系统发展史 只有硬件没有软件的计算机系统被称之为"裸机",我们很难用"裸机"来完成计算机日常的工作(如存储和运 ...

  7. python实现登录支付宝收能量_适合零基础人群学习的Python入门教程

    适合零基础人群学习的Python入门教程学什么?小编为大家准备的Python学习教程,课程主要讲解:Python核心编程.Linux基础.前端开发.Web开发.爬虫开发.人工智能等内容. 对于初学者想 ...

  8. Python培训教程:Python有哪些比较重要的内置函数?

    学习Python技术或者参加Python工作的小伙伴们应该都知道,在Python编程语言中会经常出现很多内置函数,很少有人清楚这些函数,但是它的功能是不可小觑的,下面小编就为大家详细介绍一下Pytho ...

  9. Python培训教程分享:10款超好用的Python开发工具

    学会Python技术后,我们在参加工作的时候如果能有辅助工具的话,那么会很大程度的提高我们的工作效率,那么Python都有哪些好用的开发工具呢?下面小编就为大家详细的介绍一下10款超好用的Python ...

最新文章

  1. 当你学了现在的忘了前面的
  2. “可扩展标记语言”(XML) 提供一种描述结构化数据的方法。
  3. BZOJ4855 : [Jsoi2016]轻重路径
  4. 修复python命令行下接收不到参数的问题
  5. exce小技巧,Mac Excel单元格内换行快捷键
  6. pandas学习之透视表
  7. Principle 5.14 完美汉化版 Mac平台交互动效设计神器
  8. 联想G460驱动问题
  9. DarkGDK的杯具体验
  10. python百度unit_Python——在调用Baidu的unit接口时,如何设置意向置信度,使其始终返回第一个say,实现,百度,UNIT,意图,总是...
  11. 液晶显示屏的分辨率详解?
  12. overleaf 中相关的问题
  13. microsoftstore连不上网_Microsoft Store登录不了怎么办 Microsoft Store登录不了解决方法...
  14. 在红帽linux创建目录,redhat linux建文件系统
  15. 音频处理工具 sox 使用
  16. 网站与服务器维护怎么做?
  17. 考HCIP是否只考背题就能考过?
  18. 算法基础2 —— OJ入门以及暴力枚举
  19. Josh 的学习笔记之数字通信(Part 3——基带信号解调与检测)
  20. 搜狐合并Chinaren.com (转)

热门文章

  1. 电子纸墨水屏的现实应用场景
  2. Elasticsearch总结
  3. 计算与算计的区别是:
  4. Python数据分析案例-利用AB test分析转化率是否存在差异
  5. 用VR手捏3D模型,PS直接与甲方对线,Adobe新技术确实给设计师炫到了
  6. 国家标准征求意见稿出台,刷脸支付迎来新进展
  7. Ubuntu登录设置,切换密码登录或是密钥登陆
  8. FQDN与域名的区别
  9. EBS 报表开发:即时打印单据@WEB PL/SQL + WEB.SHOW_DOCUMENT(1)
  10. Annotation PK Interface