多任务:同一时间执行多个任务
表现:
-
并发
在一段时间内交替执行多个任务
单核计算机都是并发,只是交叉时间很短,所以被认为是同时进行
并发的本质:切换+保存状态 -
并行:在一定时间内真正的同时一起执行多个任务
优点:充分利用CPU资源,提升程序执行效率 -
进程与线程的关系
1.进程是线程的容器,一个进程最小有一个线程来执行它的程序,同时线程不拥有系统资源:
2.线程可与同一进程内的其他资源共享进程所有的全部资源
对比: -
关系对比:1.线程是依附在进程里面的,没有进程就没有线程:2.一个进程默认提供一条线程,进程可以创建多个线程:
区别对比:1.创建进程的资源开销比创建线程的资源开销大:2.进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位:3.线程不能单独运行,必须依赖进程 -
优缺点对比:进程:优点:可以用多核:缺点:资源开销大:线程:优点:资源开销小:缺点:不可以用多核
进程
概念
资源分配的最小单位,是操作系统进行资源分配和调度运行的基本单位
会分配CPU、内存、磁盘、网路等资源
进程的三种基本状态
就绪状态
执行状态
阻塞状态
在一些系统中,进程还有一种很重要的状态是:挂起状态(是该进程暂时不接受调度)
另外,在实际系统中,为管理需要,还存在着两种比较常见的状态:创建状态和终止状态
多进程的作用
提高程序执行效率
多进程完成多任务实战
import multiprocessing
from time import sleep
import os
# 函数定义
def sing(num):
# 获取进程编号
print("唱歌进程的编号是:",os.getpid())
for i in range(num):
print("第 {0} 次唱歌".format(i))
sleep(1)
def dance(num):
# 获取进程编号
print("跳舞进程的编号是:{0}".format(os.getpid()))
for i in range(num):
print("第 {0} 次跳舞".format(i))
sleep(1)
if __name__ == '__main__':
# group=None, target=None, name=None
# target 执行的目标任务名,一般是函数名或者方法名
# name 进程名字,一般不设置,系统会自动设置,process-1 -2等
# group=None 进程组
# args = (), 表示以元组方式传参,逗号不可以省略,元组的元素顺序与函数中的形参要顺序一致
# kwargs = {} 表示以字典方式传参 字典的键与参数名称相同,多个参数只要保证key与形参名称一致即可
# 主进程创建子进程 注意函数名没有引号,没有括号
sing_progress = multiprocessing.Process(target=sing,args=(5,))
dance_progress = multiprocessing.Process(target=dance,kwargs={"num":3})
# 将子进程设置成守护进程,一旦主进程结束,所有的子进程都会自动销毁掉
sing_progress.daemon = True
# 启动进程
sing_progress.start()
dance_progress.start()
多线程任务实战
import threading
from time import sleep
import os
# 函数定义
def sing():
for i in range(3):
print("第 {0} 次唱歌".format(i))
sleep(1)
def dance():
# 获取进程编号
# print("跳舞进程的编号是:{0}".format(os.getpid()))
for i in range(3):
print("第 {0} 次跳舞".format(i))
sleep(1)
def task():
sleep(1)
info = threading.current_thread()
print("第{0}个线程的线程信息".format(info))
if __name__ == '__main__':
# group=None, target=None, name=None
# target 执行的目标任务名,一般是函数名或者方法名
# name 进程名字,一般不设置,系统会自动设置 thread-1 -2等
# group=None
# args = (), 表示以元组方式传参,逗号不可以省略,元组的元素顺序与函数中的形参要顺序一致
# kwargs = {} 表示以字典方式传参 字典的键与参数名称相同,多个参数只要保证key与形参名称一致即可
# daemon 是否设置为守护线程
# sing_thread = threading.Thread(target=sing)
# dance_thread = threading.Thread(target=dance,daemon=True)
#
# # 一定要在start之前调用
# sing_thread.setDaemon(True)
# sing_thread.start()
# dance_thread.start()
for i in range(10):
t = threading.Thread(target=task)
t.start()
协程实战
# 真正的协程模块就是使用greenlet完成的切换
from greenlet import greenlet
def eat(name):
print('%s eat 1' % name) # 2
g2.switch('taibai') # 3
print('%s eat 2' % name) # 6
g2.switch() # 7
def play(name):
print('%s play 1' % name) # 4
g1.switch() # 5
print('%s play 2' % name) # 8
g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch('taibai') # 可以在第一次switch时传入参数,以后都不需要 #1
网友评论