并发编程,装饰器

Python基础学习笔记DAY12

并发编程

1.概述
(1)非并发
【1】程序由单个步骤序列组成
【2】包含独立子任务的程序执行性能低
(2)并发
【1】异步,高效
【2】分解子任务、简化流程与逻辑
(3)进程 process
【1】一个程序的执行实例
【2】每个进程都有自己的地址空间、内存、数据线及辅助数据
(4)线程 thread
【1】同一进程内,可被并行激活的控制流
【2】空想相同上下文(空间地址、数据结构)
【3】特点:便于信息共享和通信
【4】线程访问顺序差异会导致结果不一致(条件 race condition)
(5)python全局解释器锁
【1】Global Interpreter Lock
【2】Python代码有虚拟机(解释器主循环)控制
【3】主循环同时只能有一个控制线程执行
2.单线程:

import time
def worker(n):
    print(f'函数执行开始于:{time.ctime()}')
    time.sleep(n)
    print(f'函数执行结束于:{time.ctime()}')

def main():
    print(f'[主函数执行开始于:{time.ctime()}]')
    worker(4)
    worker(2)
    print(f'[主函数执行开始于:{time.ctime()}]')

3.多线程
(1)内置_thread模块
【1】没有控制进程结束机制
【2】只有一个同步原语(锁)
【3】功能少于threading模块

.start_new_thread(function, args, **kwargs=n)

import time
import _thread

def worker(n):
    print(f'函数执行开始于:{time.ctime()}')
    time.sleep(n)
    print(f'函数执行结束于:{time.ctime()}')

def main():
    print(f'[主函数执行开始于:{time.ctime()}]')
    _thread.start_new_thread(worker,(4,)) //要已元组方式给值
    _thread.start_new_thread(worker,(2,))

    time.sleep(6)
    worker(2)
    print(f'[主函数执行开始于:{time.ctime()}]')

(2)threading模块
【1】.Thread线程类

  • 构造:
    • .Thread(target = 目标函数, args = (参数,))
    • .自定义Thread派生类,重写run方法逻辑

【2】.start() 启动线程
【3】.join() 要求主线程等待
【4】.current_thread() 获取当前线程
【5】.name 线程名称

import time
import threading
//方法1(现已被淘汰)
def worker(n):
    print('{threading.current_thread().name}函数执行开始于:{}'.format(time.ctime()))
    time.sleep(n)
    print('{threading.current_thread().name}函数执行结束于:{}'.format(time.ctime()))

def main():
    print(f'[住函数执行开始于:{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(f'[住函数执行结束于:{time.ctime()}]')
//方法2
def worker(n):
    print('{threading.current_thread().name}函数执行开始于:{}'.format(time.ctime()))
    time.sleep(n)
    print('{threading.current_thread().name}函数执行结束于:{}'.format(time.ctime()))

class MyThread(threading.Thread):
    def __init__(selffunc,args):
        threading.Thread.__init__(self)
        self.func = func
        self.args = args

    def run(self):
        self.func(*self.args)


def main():
    print(f'[住函数执行开始于:{time.ctime()}]')

    threads = []
    t1 = MyThread(worker, (4,))
    threads.append(t1)
    t1 = MyThread(worker, (2,))
    threads.append(t2)

for t in threads:
    t.start()

for t in threads:
    t.join() //告诉主线程等待当前线程执行完毕

    print(f'[住函数执行结束于:{time.ctime()}]')

(3)threading.Lock 同步原语 – 锁 – 需要共享的数据操作时用
【1】.acquire() 获得
【2】.release() 释放

import threading
import time
import random

eggs = []
lock - threading.Lock()

def put_egg (n, lst):
    lock.acqire()    
    for i in range (1,n+1)
        time.sleep(random,randint(0,2))
        lst.append(i)
    lock.release()

【3】支持上下文操作 with lock:

import threading
import time
import random


def put_egg (n, lst):
    with lock:   
        for i in range (1,n+1)
            time.sleep(random,randint(0,2))
            lst.append(i)


def main():
    treads = []
    for i in range (3):
        t - threading.Thread (target = put_egg, args = (5, eggs))
        threads.append(t)

    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print(eggs)

4.队列
(1)queue模块
【1】Queue 先进先出队列 FIFO —1.Queue(maxsize = 0) 构造实例

  • .put(block = True, timeout = None)放入数据项
  • .get(block = True, timeout = None) 获取数据项
  • .ask_done() 声明当前队列任务处理完毕
  • .join() 队列所有项处理完毕前阻塞
    【2】LifoQueue 后进先出队列 LIFO
    【3】PriortyQueue 优先队列
import threading
import queue
import time
import random


def producer(data_queue):
    for i in range(5):
        time.sleep(0,5)
        item = random.randint(1,100):
        data_queue.put(item)
        print(f'{threading.current_thread().name}在队列中放入数据项:{item}')

def consumer(data_queue):
    while True:
        try:
            item = data_queue.get(timeout = 3)
            print(f'{threading.current_thread().name}从队列中移除了{item}')
        except queue.Empty:
            break
        else:
            data_queue.tast_done()


def main():
    q = queue.Queue()
    threads = []
    p = threading.Thread(target = producer, args= (q,))
    p.start()

    for i in range (2):
        c = threading.Thread(target = consumer, arg = (q,))
        p.start()

    for t in threads:
        t.start()

    for t in threads:
        t.join()
    q.join()

if __name__ == '__main__':
    main()

5.IO操作首选多线程

(1)multiprocessing模块

计算操作用别的首先实现并发较好

充分运用多核,多CPU的计算能力,适用于计算密集型任务

import time
import multiprocessing

def func(n):
    print(f'{multiprocessing.current_process().name}执行开始于:{time.ctime()}')
    time.sleep(n)
    print(f'{multiprocessing.current_process().name}执行开始于:{time.ctime()}')

def main ():
    print(f'主函数运行于:{time.ctime()}')
        processes = []
    p1 = multiprocessing.Process(target = func, args = (4,))
    processes.append(p1)
    p2 = multiprocessing.Process(target = func, args = (2,))
    processes.append(p2)

    for p in processes:
        p.start()
    for p in procsses:
        p.join()

    print(f'主函数结束于:{time.ctime()}')

if __name__ =='__main__':
    main()

(2)concurrent.futures模块(抽象层)

【1】IO密集型 – 多线程 – ThreadPoolExecutor

【2】计算密集型 – 多进程 – ProcessPoolExecutor

顺序执行,多线程执行,多进程执行代码比较

import time
import concurrent.futures

numbers  = list (range(1,11))

def count(n)
    for i in range(1000000):
        i+=1
    return i* n

def worker(x):
    result count(x)
    print(f'数字:{x}的计算结果是{result}')

//顺序执行
def sequntial_execution():
    start_time.clock()
    for i in numbers:
        worker(i)
    print(f'顺序执行花费时间:{tim() - start_time}秒')

//多线程执行
def threading_execution():
    start_time = time.clock()
    with concurrent.futures.ThreadPoolExecutor(max_workers = 5) as excutor:
        for i in numbers:
            executor.submit(worker,i)
    print(f'顺序执行花费时间:{tim() - start_time}秒')

//进程池执行
def process_execution():
    start_time = clock.clock()
    with concurrent.futures.ProcessPoolExecutor(max_workers = 5) as excutor:
        for i in numbers:
            executor.submit(worker,i)
    print(f'顺序执行花费时间:{tim() - start_time}秒')


if __name__ == '__main__':
    sequential_excution()
    threading_excution()
    process_execution()

装饰器

1.用于管理和增强函数和类行为的代码
2.提供一种在函数或类定义中插入自动运行代码的机制
3.特点:
(1)语法更明确
(2)更高的代码可维护性
(3)更好的一致性
4.函数基础
(1)函数可以赋给另外一个变量

def hello(name):
    print('Hello',name)

greeting = hello
greeting('Tom')  //返回Hello Tom
hello('Jerry')  //返回Hello Jerry

(2)将函数作为参数传递

def add(a,b):
    return a+b

def subtracy(a,b):
    return a - b

def action(x,y,func):  //委托
    return func(x,y)

action(5,3,add)

(3)函数嵌套及跨域返回

def greeting():
    def hello():
        return 'Hello'
    return hello() 
greeting()  //返回hello()的结果

def greeting():
    def hello():
        return'Hello'
    return hello 
greeting()  //返回函数对象
greeting()()   //返回hello()的结果

//跨越访问:
def func_1():
    x = 10
    def func_2():
        x= 20
        return x+10
    return func_2()

func_1()  //返回30
def func_1():
    x = 10
    def func_2():
        nonlocal x   //上一层的x
        return x+10
    return func_2()

func_1()  //返回20

5.编写装饰器

(1)函数定义装饰器

可用于

  • 脚本里的普通函数上
  • 用在另外一个类定义的方法上
def p_decorator(func):
    def wrapper(*args,**kwargs):
        return '<p>' + func(*args,**kwargs) +'</p>'
    return wrapper

@p_decorator
def get_text():
    return '欢迎学习'

if __name__ =='__main__':
    print(get_text())

//或:
def p_decorator(func):
    def wrapper(*args,**kwargs):
        return '<p>' + func(*args,**kwargs) +'</p>'
    return wrapper

def get_text():
    return '欢迎学习'

if __name__ =='__main__':
    html = p_decorator(get_text)
    print(html())


//修饰带参数的情况
def p_decorator(func):
    def wrapper(*args,**kwargs):
        return '<p>' + func(*args,**kwargs) +'</p>'
    return wrapper

@p_decorator
def get_upper_text(text):
    return text.upper()

if __name__ =='__main__':
    html = p_decorator(get_text)
    print(html())

(2)类定义装饰器(只能用于脚本里的普通函数上)

class P:
    def __init(self,func):
        self.func = func   

    def __call__(self, *args, **kwargs):
        return '<p>' + self.func(*args, **kwargs) + '</p>'

@P
def get_text():
    return '欢迎学习'

@P
def get_upper_text (text):
    return text.upper()

if __name__ == '__main__':
    print(get_upper_text('abc'))

(3)若添加装饰器顺序为:

@div_decorator
@p_decorator
则先加p标签,再加div标签

(4)装饰器的参数

def tags(tag):
    def tag_decorator(func):
        def wrapper(*args, **kwargs):
            return f'<{tag}>{func(*args,**kwargs)}</{tag}>'
        return wrapper
    return tag_decorator

@tags('p')
def get_upper_text(text):
    return text.upper()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值