文章目录
- 前言
- 一、执行方式
- 1、并发
- 1、并发
- 二、协程
- 三、线程
- 三、进程
前言
单任务,也就是说一个函数或者方法执行完成,另外一个函数或者方法才能执行;而多任务能够让两个以上函数或者方法同时执行。多任务编程充分利用CPU资源,提高程序的执行效率。
一、执行方式
1、并发
在一段时间内交替去执行任务;但是,由于CPU的执行速度实在是太快了,我们感觉就像这些软件都在执行同时一样;单核cpu是并发的执行多任务的。
1、并发
在多核cpu处理多任务,多个内核是真正的一起执行软件;多核cpu是并行的执行多任务,始终有多个一起执行。
二、协程
是python个中另外一种实现多任务的方式;只不过比线程占用更小执行单元;优势就是协程极高的执行效率。
import gevent
def f(n):
for i in range(n):
print(gevent.getcurrent(), i)
g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)
g1.join()
g2.join()
g3.join()
三、线程
是cpu调度的基本单位;每个进程至少都有一个线程,而这个线程就是我们通常说的主线程;线程实现多任务的另外一种方式。
import threading # 导入线程包
import time
'''
线程类Thread
group: 线程组,目前只能使用None
target: 执行的目标任务名
args: 以元组的方式给执行任务参传
kwargs: 以字典方式给执行任务参传
name: 线程名,一般不用设置
启动线程
start方法
'''
sum = 0 # 线程之间共享全局变量;线程之间共享全局变量数据出现错误问题
lock = threading.Lock() # 创建互斥锁;互斥锁: 对共享数据进行锁定,保证同一时刻只能有一个线程去操作。
def run(count):
lock.acquire() # 上锁
global sum
for _ in range(count):
sum += 1
print("跑")
time.sleep(0.2)
if sum > 2:
lock.release() # 死锁示例;在合适的地方释放锁
return
lock.release() # 解锁
print(sum)
def dance(count):
lock.acquire()
global sum
for _ in range(count):
sum += 1
print("跳")
time.sleep(0.2)
lock.release()
print(sum)
'''
线程之间执行是无序的,run和dance的执行没有顺序;它是由cpu调度决定的
主线程会等待所有的子线程执行结束再结束
设置守护主线程有两种方式:
threading.Thread(target=show_info, daemon=True)
线程对象.setDaemon(True)
'''
if __name__ == '__main__':
r = threading.Thread(target=run, args=(4,))
d = threading.Thread(target=dance, kwargs={"count": 4})
r.start()
# r.join() # 线程等待(join);线程同步: 保证同一时刻只能有一个线程去操作全局变量
d.start()
三、进程
一个正在运行的程序(软件)就是一个进程,是运营进程进行资源分配的基本单位;进程是实现多任务的一种方式。一个程序运行后至少有一个进程,一个进程默认有一个线程;进程里面可以创建多个线程。
import multiprocessing # 导入进程包
import time
import os
'''
Process进程类
group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字
args:以元组方式给执行任务参传
kwargs:以字典方式给执行任务参传
Process创建的实例对象的常用方法:
start():启动子进程实例(创建子进程)
join():等待子进程执行结束
terminate():不管任务是否完成,立即终止子进程
'''
sum = 0 # 定义一个全局变量;进程之间不共享全局变量
def run(count):
global sum
print("run:", os.getpid())
print("run:", multiprocessing.current_process())
print("run:", os.getppid()) # 获取父进程的编号
for i in range(count):
print("跑")
time.sleep(1)
sum += 1
# os.kill(os.getpid(), 9)
print(sum)
def dance(count):
global sum
print("dance:", os.getpid())
print("dance:", multiprocessing.current_process())
print("dance:", os.getppid()) # 获取父进程的编号
for i in range(count):
print("跳")
time.sleep(1)
sum += 1
# os.kill(os.getpid(), 9) # 根据进程编号杀死指定进程,进程被杀死,之后的代码不在执行
print(sum)
if __name__ == '__main__':
print("main:", os.getpid()) # os.getpid()表示获取当前进程的编号
print("main:", multiprocessing.current_process()) # 获取当前进程
print("main:", os.getppid()) # 获取父进程的编号
r = multiprocessing.Process(target=run, kwargs={"count": 4}) # 字典方式传参(kwargs): 字典方式传参字典中的key一定要和参数名保持一致。
r.daemon = True # 设置守护进程,主进程退出,子进程直接销毁
d = multiprocessing.Process(target=dance, args=(3,)) # 元组方式传参(args): 元组方式传参一定要和参数的顺序保持一致。
d.daemon = True
r.start()
d.start()
time.sleep(2) # 主进程会等待所有的子进程执行完成以后程序再退出
print("over")
# r.terminate()#销毁子进程来达到主进程退出,因为主进程会等待所有的子进程执行完成以后程序再退出
# d.terminate()
exit()
#************************************************#
"C:\Program Files\JetBrains\python\python.exe" "F:/PyCharm 2019.1.3/PycharmProject/1.py"
main: 5180
main: <_MainProcess(MainProcess, started)>
main: 11700
run: 2316
run: <Process(Process-1, started daemon)>
run: 5180
跑
dance: 11396
dance: <Process(Process-2, started daemon)>
dance: 5180
跳
跑
跳
over
Process finished with exit code 0