Python基础学习(十二)—– 线程、函数

756-周同学

发表文章数:47

热门标签

,
首页 » Python » 正文

一. 并发编程

1. 概述

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

2. 多线程

  1. _thread(不建议使用)
    (1)特点:没有控制进程结束的机制,只有一个同步原语(锁),功能少于threading模块
import time
import _thread

def worker(n):
    print(f'time start: {time.ctime()}')
    time.sleep(n)
    print(f'time end: {time.ctime()}') #获取当前线程

def main():
    print(f'[start: {time.ctime()}]')
    _thread.start_new_thread(worker,(4,)) #开始线程
    _thread.start_new_thread(worker,(2,))

    time.sleep(4)
    print(f'[end: {time.ctime()}]')

if __name__ == '__main__':
    main()
  1. threading模块
    (1) .Thread 线程类
import time
import threading

def worker(n):
    print(f'{threading.current_thread().name}time start: {time.ctime()}')
    time.sleep(n)
    print(f'{threading.current_thread().name}time end: {time.ctime()}')

def main():
    print(f'[start: {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'[end: {time.ctime()}]')

if __name__ == '__main__':
    main()

自定义一个派生类

import time
import threading

def worker(n):
    print(f'{threading.current_thread().name}time start: {time.ctime()}')
    time.sleep(n)
    print(f'{threading.current_thread().name}time end: {time.ctime()}')

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

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

def main():
    print(f'[start: {time.ctime()}]')
    threads = []

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

    for t in threads:
       t.start()

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

    print(f'[end: {time.ctime()}]')

if __name__ == '__main__':
    main()

(2). 同步原语:锁
.acquire() .release, with lock:

import threading
import time
import random

eggs = []
lock = threading.Lock()

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

def main():
    threads = []

    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)

if __name__ == '__main__':
    main()

3. 队列

  1. queue 模块
    (1) Queue FIFO 先进先出
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} input:{item}')

def consumer(data_queue):
    while True:
        try:
            item = data_queue.get(timeout=3) #获取数据
            print(f'{threading.current_thread().name} remove:{item}')
        except queue.Empty:
            break
        else:
            data_queue.task_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,args=(q,))
        threads.append(c)

    for t in threads:
        t.start()

    for t in threads:
        t.join()

    q.join() #队列处理完毕前阻塞

if __name__ == '__main__':
    main()

(2) LifoQueue LIFO 后进先出
(3) PriorityQueue 优先权

4. multipleprocessing 模块

  1. 充分运用多核、多CPU的计算能力,适用于计算密集型任务
import time
import multiprocessing

def func(n):
    print(f'{multiprocessing.current_process().name}start:{time.ctime()}')
    time.sleep(n)
    print(f'{multiprocessing.current_process().name}end:{time.ctime()}')

def main():
    print(f'principal start:{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 processes:
        p.join()

    print(f'principal end:{time.ctime()}')

if __name__ == '__main__':
    main()

5. concurrent.futures 模块

  1. ThreadPoolExecutor
  2. ProcessPoolExecutor
import time
import concurrent.futures

numbers = list(range(1,11))

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

def worker(x):
    result = count(x)
    print(f'number:{x} result :{result}')

#顺序执行
def sequential_execution():
    start_time = time.clock()
    for i in numbers:
        worker(i)
    print(f'time:{time.clock()-start_time}second')

#多线程执行
def threading_execution():
    start_time = time.clock()
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for i in numbers:
            executor.submit(worker,i)

    print(f'time:{time.clock()-start_time}second')

#多进程执行
def processing_execution():
    start_time = time.clock()
    with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
        for i in numbers:
            executor.submit(worker, i)

    print(f'time:{time.clock() - start_time}second')

if __name__ == '__main__':
    #sequential_execution()
    #threading_execution()
    processing_execution()

二. 装饰器

1. 概述

  1. 用于管理和增强函数和类行为的代码
  2. 提供一种在函数或类定义中插入自动运行代码的机制
  3. 特点
    (1)更明确的语法
    (2)更真的代码可维护性
    (3)更好的一致性

2. 编写

  1. 函数基础
    (1)将函数赋给变量
def hello(name):
...    print('Hello',name)
...    
hello('Tom')
Hello Tom
greeting = hello
greeting('Jerry')
Hello Jerry

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

def add(a,b):
...    return a+b
...
def subtract(a,b):
...    return a-b
def action(x,y,func):
...    return func(x,y)
...
action(5,3,add)
8
action(5,3,subtract)
2
action(5,3,lambda x,y:x*y)
15

(3) 函数嵌套及跨域处理

def greeting():
...    def hello():
...        return 'Hello'
...    return hello()
...
greeting()
'Hello'

def greeting():
...    def hello():
...        return 'Hello'
...    return hello
...
greeting()
<function greeting.<locals>.hello at 0x110a37c80>
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
...        return x+10
...    return func_2()
...
func_1()
20
  1. 函数定义装饰器
def p_decorator(func): #修饰函数
    def wrapper(*args,**kwargs): #装饰函数
        return '<p>' + func(*args,**kwargs) + '</p>' #返回原函数的执行结果
    return wrapper

@p_decorator
def get_text():
    return 'welcome'

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

if __name__ == '__main__':
    #html = p_decorator(get_text)
    #print(html())
    print(get_text())
    print(get_upper_text('www.code.com'))
  1. 类定义装饰器
class P:
    def __init__(self,func):
        self.func = func

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

class Student:
    def __init__(self,name):
        self.name = name

    @P ##不可用,但是函数装饰器可用
    def get_name(self):
        return self.name.upper()

@P
def get_text():
    return 'welcome'

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

if __name__ == '__main__':
    s = Student('Mike')
    print(s.get_name())
    #print(get_text())
    # print(get_upper_text('www.code.com'))
  1. 装饰器参数
#参数化装饰器
def tags(tag):
    def tag_decorator(func):
        def wrapper(*args, **kwargs):  # 装饰函数
            return f'<{tag}>{func(*args, **kwargs)}</{tag}>'
        return wrapper
    return tag_decorator

def p_decorator(func): #修饰函数
    def wrapper(*args,**kwargs): #装饰函数
        return '<p>' + func(*args,**kwargs) + '</p>' #返回原函数的执行结果
    return wrapper

class Student:
    def __init__(self,name):
        self.name = name

    @p_decorator
    def get_name(self):
        return self.name.upper()

def div_decorator(func): #修饰函数
    def wrapper(*args,**kwargs): #装饰函数
        return '<div>' + func(*args,**kwargs) + '</div>'
    return wrapper

def get_text():
    return 'welcome'

@tags('div')
@tags('p')
def get_upper_text(text):
    return text.upper()

if __name__ == '__main__':
    print(get_upper_text('www.code.com'))
标签:

未经允许不得转载:作者:756-周同学, 转载或复制请以 超链接形式 并注明出处 拜师资源博客
原文地址:《Python基础学习(十二)—– 线程、函数》 发布于2020-04-04

分享到:
赞(0) 打赏

评论 抢沙发

评论前必须登录!

  注册



长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Vieu3.3主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录