Python多任务教程
一.并发和并行
多任务:一定时间段内,充分利用cpu资源,同时去执行多个任务
并发: 快速交替的 去执行多任务
并行: 真正同时的 去执行多任务 ,就是同时进行
二.多进程
1.多进程入门
知识点:
进程含义: 运行中的程序
进程特点: cpu资源分配的 最小单位
多进程模块: multiprocessing
进程类: Process
使用步骤:
导包 : import multiprocessing
创建对象 : 子进程对象 = multiprocessing.Process(target=任务名)
开启进程 : 子进程对象.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.获取当前进程信息
知识点:
获取当前进程对象: multiprocessing.current_process()
获取当前进程name: multiprocessing.current_process().name
获取当前进程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.多线程入门
知识点:
线程含义: 进程中 执行代码的 一个分支 (一个进程至少有一个线程)
线程作用: 线程是 cpu调度的 最小单位
多线程模块: threading
线程类: Thread
使用步骤:
- 导包 : import threading
- 创建对象 : 子线程对象 = threading.Thread(target=任务名)
- 开启进程 : 子线程对象.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.多线程注意事项
- 多线程是在一个进程中
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.获取当前线程信息
知识点:
获取当前线程对象:threading.current_thread()
获取当前线程name:threading.current_thread().name
获取当前线程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()
四.进程和线程对比
关系
线程是依附在进程里面的,没有进程就没有线程
一个进程默认提供一条线程,进程可以创建多个线程
区别
- 进程之间不共享全局变量
- 线程之间共享全局变量,但是要注意资源竞争的问题,解决办法是互斥锁或者线程同步
- 创建进程的资源开销要比创建线程的资源开销要大
- 进程是操作系统 资源分配 的基本单位,线程是 CPU调度 的基本单位
- 线程不能够独立执行,必须依存在进程中
- 多进程开发比单进程多线程开发稳定性要强
优缺点
进程优缺点:
优点:可以用多核
缺点:资源开销大
线程优缺点:
优点:资源开销小
缺点:不能使用多核
Python多任务教程相关推荐
- 大学python用什么教材-Python大学教程(普通高等教育十三五规划教材)
导语 内容提要 吕云翔.赵天宇.张元编著的<Python大学教程>介绍了使用Python语言进行程序设计的方法及其应用. 全书共14章,分为三部分.第一部分为基础篇(第1-5章),主要介绍 ...
- python多线程教程_Python多线程编程教程【2小时学会】
Python多线程编程教程[2小时学会] 中级共14课 从0开始学习python多任务编程,想了解python高并发实现,从基础到实践,通过知识点 + 案例教学法帮助你想你想迅速掌握python多任务 ...
- Python学习教程(Python学习路线):Day13-进程和线程
Python学习教程(Python学习路线):进程和线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持"多任务"的操作系统,这使得我们可以同时运行多 ...
- Python是什么?Python基础教程400集大型视频,全套完整视频赠送给大家
2020最新Python零基础到精通资料教材,干货分享,新基础Python教材,看这里,这里有你想要的所有资源哦,最强笔记,教你怎么入门提升!让你对自己更加有信心,重点是资料都是免费的,免费!!! 获 ...
- python编程教程第九讲_Python入门学习视频,最全面讲解视频无偿分享,这些基础知识你都懂了吗?...
2020最新Python零基础到精通资料教材,干货分享,新基础Python教材,看这里,这里有你想要的所有资源哦,最强笔记,教你怎么入门提升!让你对自己更加有信心,重点是资料都是免费的,免费!!! 如 ...
- Python高级教程:玩转Linux操作系统
Python高级教程:玩转Linux操作系统 操作系统发展史 只有硬件没有软件的计算机系统被称之为"裸机",我们很难用"裸机"来完成计算机日常的工作(如存储和运 ...
- python实现登录支付宝收能量_适合零基础人群学习的Python入门教程
适合零基础人群学习的Python入门教程学什么?小编为大家准备的Python学习教程,课程主要讲解:Python核心编程.Linux基础.前端开发.Web开发.爬虫开发.人工智能等内容. 对于初学者想 ...
- Python培训教程:Python有哪些比较重要的内置函数?
学习Python技术或者参加Python工作的小伙伴们应该都知道,在Python编程语言中会经常出现很多内置函数,很少有人清楚这些函数,但是它的功能是不可小觑的,下面小编就为大家详细介绍一下Pytho ...
- Python培训教程分享:10款超好用的Python开发工具
学会Python技术后,我们在参加工作的时候如果能有辅助工具的话,那么会很大程度的提高我们的工作效率,那么Python都有哪些好用的开发工具呢?下面小编就为大家详细的介绍一下10款超好用的Python ...
最新文章
- 当你学了现在的忘了前面的
- “可扩展标记语言”(XML) 提供一种描述结构化数据的方法。
- BZOJ4855 : [Jsoi2016]轻重路径
- 修复python命令行下接收不到参数的问题
- exce小技巧,Mac Excel单元格内换行快捷键
- pandas学习之透视表
- Principle 5.14 完美汉化版 Mac平台交互动效设计神器
- 联想G460驱动问题
- DarkGDK的杯具体验
- python百度unit_Python——在调用Baidu的unit接口时,如何设置意向置信度,使其始终返回第一个say,实现,百度,UNIT,意图,总是...
- 液晶显示屏的分辨率详解?
- overleaf 中相关的问题
- microsoftstore连不上网_Microsoft Store登录不了怎么办 Microsoft Store登录不了解决方法...
- 在红帽linux创建目录,redhat linux建文件系统
- 音频处理工具 sox 使用
- 网站与服务器维护怎么做?
- 考HCIP是否只考背题就能考过?
- 算法基础2 —— OJ入门以及暴力枚举
- Josh 的学习笔记之数字通信(Part 3——基带信号解调与检测)
- 搜狐合并Chinaren.com (转)