Python基础第十二天--线程--进程--装饰器定义

本文详细介绍了Python的并行编程,包括全局解释器锁(GIL)、_thread和threading模块的多线程实现、同步锁与队列、以及multiprocessing模块的多进程。同时,文章还探讨了函数基础,如装饰器的定义和使用,包括函数和类定义的装饰器,并展示了带参数的装饰器实例。
摘要由CSDN通过智能技术生成

一、并行编程概念

1、非并发,即按照顺序一步步执行,单核CPU,仍无法实现真正的并发,而多核可以多个任务一起执行,真正可以实现并行运行。
2、进程每打开一次应用,即有一次实例了,如双击一个QQ,即一个进程打开了,打开多个QQ,即有多个进程实例在运行了。
3、 同一个进程下的包含多个独立执行的线程,这些线程可以共享上下文 ,即共享的空间地址,包括一些数据结构,或一些资源。不同线程之间还可以进行信息共享通信,如下图:
在这里插入图片描述
在这里插入图片描述

Python全局解释器锁(GIL)

在这里插入图片描述
总之: Python是解释型语言,运行环境可以是虚拟机,这个虚拟机也称为解释器主循环,当运行程序时,这个解释器主循环要求每次只能有一个主要控制线程执行,因为避免多个线程同时执行时有可能导致数据不一致与状态不同步,所以即使程序中是多线程,运行时候也是一个一个执行 。所以用这个锁来切换线程,当一个线程运行完自己的字节码程序后,然后让出控制权,进入睡眠状态,让另一个线程执行。实际开发中,程序若是计算密集型消耗CPU即用多进程实现,或者底层的东西可以用c语言写,而IO密集型程序,Python会尽可能快释放锁,所以可以用Python编写。实际上只是cPython解释器有这个锁,而其他的如JavaPython解释器即没这个锁,因此这个锁,是由Python解释器运行时候加上的,与程序本身无关。

多线程之_thread模块

总概图:
在这里插入图片描述

模拟一个单线程耗时的案例

import  time
def worker(n):
    print('函数开始于:{}'.format(time.ctime()))#可以获取当前时间
    time.sleep(n)#每个子线程执行所需要时间,等待几秒
    print('函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间

def main():
    print('主函数开始于:{}'.format(time.ctime()))  # 可以获取当前时间
    worker(4)
    worker(2)
    print('主函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间
if __name__=='__main__':
    main()

测试结果:发现是一个执行完后,另一个线程再执行,即依次顺序执行的。

主函数开始于:Tue Dec 31 10:18:56 2019
函数开始于:Tue Dec 31 10:18:56 2019
函数结束于:Tue Dec 31 10:19:00 2019
函数开始于:Tue Dec 31 10:19:00 2019
函数结束于:Tue Dec 31 10:19:02 2019
主函数结束于:Tue Dec 31 10:19:02 2019

模拟多线程执行

注:不必要等一个线程执行完,你再顺序执行,而可以一起执行,先用thread模块的一些组件实现

import  time
import  _thread
def worker(n):
    print('函数开始于:{}'.format(time.ctime()))#可以获取当前时间
    time.sleep(n)#每个子线程执行所需要时间,等待几秒
    print('函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间

def main():
    print('主函数开始于:{}'.format(time.ctime()))  # 可以获取当前时间
    _thread.start_new_thread(worker,(4,))#开启第一个线程,参数1为执行的函数的引用,参数2为元组
    _thread.start_new_thread(worker, (2,))#开启第二个线程
    time.sleep(5)#让主线程等待几秒,即等待子线程执行完后再结束整个进程。
    print('主函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间
if __name__=='__main__':
    main()

测试结果:即主函数开始后,两个子线程也同时一起开始,,之后一个线程2s结束,另一个4s结束。并行各自执行各自的,并行运行了,所以总共用时4s,之后再加1s,即主线程也执行完毕了,即最后可以一起结束了。实际上main函数中 time.sleep(5)可以压缩到4s,但实际中,我们并不知道每个子任务运行时间,即休眠多长时间不知道,所以_thread模块有个锁,即在主线程运行过程中始终判断这个锁的状态,没有就等着,只有等待所有子线程执行完后,锁才释放了,主线程才结束,从而结束主进程了。所以一般不用_thread模块,麻烦

主函数开始于:Tue Dec 31 10:27:58 2019
函数开始于:Tue Dec 31 10:27:58 2019
函数开始于:Tue Dec 31 10:27:58 2019
函数结束于:Tue Dec 31 10:28:00 2019
函数结束于:Tue Dec 31 10:28:02 2019
主函数结束于:Tue Dec 31 10:28:03 2019

多线程模块之threading

第一种方式实现多线程

实例1

import  time
import  threading
def worker(n):
    print('函数开始于:{}'.format(time.ctime()))#可以获取当前时间
    time.sleep(n)#每个子线程执行所需要时间,等待几秒
    print('函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间

def main():
    print('主函数开始于:{}'.format(time.ctime()))  # 可以获取当前时间
    threads=[]#创建个线程列表,每建立一个线程即先不启动统一放到列表中,不想构造一个就启动一个,而是希望最后再一起启动执行。
    t1=threading.Thread(target=worker,args=(4,))
    threads.append(t1)
    t2= threading.Thread(target=worker, args=(2,))
    threads.append(t2)
    for  t  in  threads:
        t.start()#依次启动每个线程,
    print('主函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间
if __name__=='__main__':
    main()

测试结果:发现确实实现了并行运行,但是发现主函数都结束了,但两个子函数最后才结束。即主线程与子线程不同步问题。

主函数开始于:Tue Dec 31 10:51:24 2019
函数开始于:Tue Dec 31 10:51:24 2019
函数开始于:Tue Dec 31 10:51:24 2019
主函数结束于:Tue Dec 31 10:51:24 2019
函数结束于:Tue Dec 31 10:51:26 2019
函数结束于:Tue Dec 31 10:51:28 2019

实例2.希望子线程结束后,再一起退出,即让主线程与子线程同步。可以用join等待

import  time
import  threading
def worker(n):
    print('函数开始于:{}'.format(time.ctime()))#可以获取当前时间
    time.sleep(n)#每个子线程执行所需要时间,等待几秒
    print('函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间

def main():
    print('主函数开始于:{}'.format(time.ctime()))  # 可以获取当前时间
    threads=[]#创建个线程列表,每建立一个线程即先不启动统一放到列表中,最后再一起启动执行。
    t1=threading.Thread(target=worker,args=(4,))
    threads.append(t1)
    t2= threading.Thread(target=worker, args=(2,))
    threads.append(t2)
    for  t  in  threads:
        t.start()#在这依次启动每个线程
    for  t  in  threads:
        t.join()#即每启动一个线程后,告诉主线程你要等我结束后你才能结束。
    print('主函数结束于:{}'.format(time.ctime()))  # 可以获取当前时间
if __name__=='__main__':
    main()

测试结果:即主线程在子线程结束后,他才结束。也是并行运行的。

主函数开始于:Tue Dec 31 10:
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值