python知识点(七)--并发编程

并发编程

一、概念
1、非并发
程序由单个步骤序列构成
包含独立子任务的程序执行性能低

2、并发
1)异步
2)分解子任务、简化流程与逻辑

3、进程 process
一个程序的执行实例
每个进程有自己的地址空间、内存、数据栈及辅助数据

4、线程 thread
同一个进程内,可被并行激活的控制流
共享相同上下文(空间地址、数据结构)
特点:1) 便于信息共享与通信
2) 线程访问顺序差异会导致结果不一致(条件,race,condition)

5、Python GIL 全局解释器锁
Global Interpreter Lock
Python代码由虚拟机(解释器主循环)控制完成
主循环同时只能有一个控制线程执行

I/O密集型程序,建议使用多线程
计算密集型程序,建议使用多进程

二、多线程之threading模块
1、.Tread 线程类
通过基类去执行

import time
import threading

def worker(sleep_time):
    print('{} worker 函数开始于:{}'.format(threading.current_thread().name,time.ctime()))
    time.sleep(sleep_time)
    print('{} worker 函数结束于:{}'.format(threading.current_thread().name, time.ctime()))

if __name__ == '__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()))

通过派生类去执行

import time
import threading

def worker(sleep_time):
    print('{} worker 函数开始于:{}'.format(threading.current_thread().name,time.ctime()))
    time.sleep(sleep_time)
    print('{} worker 函数结束于:{}'.format(threading.current_thread().name, 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)

if __name__ == '__main__':
    print('主函数开始于:{}'.format(time.ctime()))

    threads = []
    t1 = MyThread(worker, (4,))
    threads.append(t1)
    t2 = MyThread(worker, (2,))
    threads.append(t2)
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print('主函数结束于:{}'.format(time.ctime()))

三、同步锁
.acquire() 获得锁
.release() 释放锁
with lock: 支持上下文操作

import time
import threading
import random

eggs = []
lock = threading.Lock()

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

def main():
    threads = []
    for i in range(0, 3):
        t = threading.Thread(target=put_eggs, args=(5,eggs))
        threads.append(t)
    for t in threads:
        t.start()
    for t in threads:
        t.join()

if __name__ == '__main__':
    main()
    print(eggs)

四、队列
queue模块

import time
import threading
import random
import queue

q = queue.Queue()

def producer(data_queue):
    for i in range(5):
        time.sleep(0.5)
        m = random.randint(1,100)
        data_queue.put(m)
        print(f'{threading.current_thread().name}往队列中添加了一个元素{m}')

def consumer(data_queue):
    while True:
        try:
            m = data_queue.get(timeout=2)
            time.sleep(random.randint(0,2))
            print(f'{threading.current_thread().name}从队列中移除了一个元素{m}')
        except queue.Empty:
            break
        else:
            data_queue.task_done()
def main():
    threads = []
    p = threading.Thread(target=producer,args=(q,))
    p.start()
    time.sleep(3)
    for i in range(0,2):
        t = threading.Thread(target=consumer, args=(q,))
        threads.append(t)
    for t in threads:
        t.start()
    for t in threads:
        t.join()

if __name__ == '__main__':
    main()
Thread-1往队列中添加了一个元素47
Thread-1往队列中添加了一个元素75
Thread-1往队列中添加了一个元素79
Thread-1往队列中添加了一个元素5
Thread-1往队列中添加了一个元素16
Thread-2从队列中移除了一个元素47
Thread-2从队列中移除了一个元素79
Thread-2从队列中移除了一个元素5
Thread-3从队列中移除了一个元素75
Thread-2从队列中移除了一个元素16

五、多进程之multiprocessing模块
用法和threading模块一样,但是多进程可以充分利用多核多CPU的计算能力,适合计算密集型程序
六、concurrent.futures 模块

import time
import threading
import random
import queue
import concurrent.futures

num_pool = list(range(1,11))

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

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

def seq_execution():
    start_time = time.clock()
    for i in num_pool:
        worker(i)
    print(f'顺序执行的耗时是:{time.clock()-start_time}秒')

def thread_execution():
    start_time = time.clock()
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for i in num_pool:
            executor.submit(worker, i)
    print(f'多线程执行的耗时是:{time.clock()-start_time}秒')

def process_execution():
    start_time = time.clock()
    with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
        for i in num_pool:
            executor.submit(worker, i)
    print(f'多进程执行的耗时是:{time.clock()-start_time}秒')


if __name__ == '__main__':
    # seq_execution()
    # thread_execution()
    process_execution()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值