第二十八章 多任务编程(Python)


前言

单任务,也就是说一个函数或者方法执行完成,另外一个函数或者方法才能执行;而多任务能够让两个以上函数或者方法同时执行。多任务编程充分利用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
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值