广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python基础之并发编程(一)
  • 666
分享到

python基础之并发编程(一)

2024-04-02 19:04:59 666人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录一、进程(Process)二、线程(Thread)三、并发编程解决方案:四、多线程实现 (两种)1、第一种 函数方法2、第二种 类方法包装五、守护线程与子线程1、线程在分法有:2

一、进程(Process)

是一个具有一定独立功能的程序关于某个数据集合的一次运行活动

二、线程(Thread)

操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进 程中的实际运作单位。

三、并发编程解决方案:

1、多任务的实现有 3 种方式:

  • 多进程模式;
  • 多线程模式;
  • 多进程+多线程模式

四、多线程实现 (两种)

1、第一种 函数方法


# 方法包装-启动多线程
from threading import Thread 
from time import sleep, time 
def func1(name): 
    print("Threading:{} start".fORMat(name)) 
    sleep(3) 
    print("Threading:{} end".format(name)) 
if __name__ == '__main__': 
    # 开始时间 
    start = time() 
    # 创建线程列表 
    t_list = [] 
    # 循环创建线程 
    for i in range(10): 
        t = Thread(target=func1, args=('t{}'.format(i),)) 
        t.start() 
        t_list.append(t) 
    # 等待线程结束 
    for t in t_list: 
        t.join() 
    # 计算使用时间 
    end = time() - start 
    print(end)

2、第二种 类方法包装


# 类包装-启动多线程 
from threading import Thread 
from time import sleep, time 
class MyThread(Thread): 
    def __init__(self,name): 
        Thread.__init__(self) 
        self.name =name 
    def run(self): 
        print("Threading:{} start".format(self.name)) 
        sleep(3) 
        print("Threading:{} end".format(self.name)) 
if __name__ == '__main__': 
    # 开始时间 
    start = time() 
    # 创建线程列表 
    t_list = [] 
    # 循环创建线程 
    for i in range(10): 
        t = MyThread('t{}'.format(i)) 
        t.start() 
        t_list.append(t) 
    # 等待线程结束 
    for t in t_list: 
        t.join() 
    # 计算使用时间 
    end = time() - start 
    print(end)

注意:

主线程不会等待子线程运行结束,如果需要等待可使用 join()方法不要启动线程后立即 join(),很容易造成串行运行,导致并发失效

五、守护线程与子线程

1、线程在分法有:

主线程:程序的本身

子线程:在程序另开起的线程

2、守护线程

主要的特征是它的生命周期。主线程死亡,它也就随之 死亡


# 类包装-启动多线程 
from threading import Thread 
from time import sleep, time 
class MyThread(Thread): 
    def __init__(self,name): 
        Thread.__init__(self) 
        self.name =name 
    def run(self): 
        print("Threading:{} start".format(self.name)) 
        sleep(3) 
        print("Threading:{} end".format(self.name)) 
if __name__ == '__main__': 
    # 开始时间 
    start = time() 
    # 循环创建线程 
    for i in range(10): 
        t = MyThread('t{}'.format(i)) 
        t.setDaemon(True)
        t.start() 
    # 计算使用时间 
    end = time() - start 
    print(end)

六、锁


from threading import Thread 
def func1(name): 
    print('Threading:{} start'.format(name)) 
    global num 
    for i in range(50000000): # 有问题 
    #for i in range(5000): # 无问题 
        num += 1 
    print('Threading:{} end num={}'.format(name, num))
if __name__ == '__main__': 
    num =0 
    # 创建线程列表 
    t_list = [] 
    # 循环创建线程 
    for i in range(5): 
        t = Thread(target=func1, args=('t{}'.format(i),)) 
        t.start() 
        t_list.append(t) 
    # 等待线程结束 
    for t in t_list: 
        t.join()

python 使用线程的时候,会定时释放 GIL 锁,这时会 sleep,所以才会出现上面的问题。 面对这个问题,如果要解决此问题,我们可以使用 Lock 锁解决此问题( 加锁的目的是:保证数据安全


from threading import Thread,Lock 
def func1(name):
    # 获取锁
    lock.acquire()
    with lock:
        global count
        for i in range(100000):
            count += 1
    # 释放锁 
    lock.release()
if __name__ == "__main__":
    count = 0
    t_list = []
    # 创建锁对象
    lock = Lock()
    for i in range(10):
        t = Thread(target=func1,args=(f't{i+1}',))
        t.start()
        t_list.append(t)
    for t in t_list:
        t.join()
    print(count)

七、死锁


from threading import Thread, Lock #Lock 锁 同步锁 互斥锁
from time import sleep 
def fun1(): 
    lock1.acquire() 
    print('fun1 拿到键盘') 
    sleep(2) 
    lock2.acquire() 
    print('fun1 拿到鼠标') 
    lock2.release() 
    print('fun1 释放鼠标') 
    lock1.release() 
    print('fun1 释放键盘') 
def fun2(): 
    lock2.acquire() 
    print('fun2 拿到鼠标') 
    lock1.acquire() 
    print('fun2 拿到键盘') 
    lock1.release() 
    print('fun2 释放键盘') 
    lock2.release() 
    print('fun2 释放鼠标') 
if __name__ == '__main__':
    lock1 = Lock() 
    lock2 = Lock() 
    t1 = Thread(target=fun1) 
    t2 = Thread(target=fun2) 
    t1.start() 
    t2.start()

from threading import RLock
'''
Lock 锁 同步锁 互斥锁
RLock 递归锁
'''
def func1():
    lock.acquire()
    print('func1获取锁')
    func2()
    lock.release()
    print('func1释放锁')
def func2():
    lock.acquire()
    print('func2获取锁')
    lock.release()
    print('func2释放锁')
def func3():
    func1()
    func2()
if __name__ == "__main__":
    #lock = Lock()  会产生错误 
    lock = RLock()
    func3()

八、信号量(Semaphore)

我们都知道在加锁的情况下,程序就变成了串行,也就是单线程,而有时,我们在不用考 虑数据安全时,为了避免业务开启过多的线程时。我们就可以通过信号量(Semaphore)来 设置指定个数的线程。(比如:电梯每次只能承载三个人,那么同时只能有三个人乘坐,其他人只能等别人做完才能乘坐)


from time import sleep
from threading import Thread
from threading import BoundedSemaphore
def index(num):
    lock.acquire()
    print(f'第{num}个人乘坐!!')
    sleep(2)
    lock.release()
if __name__ == "__main__":
    lock = BoundedSemaphore(3)
    for i in range(10):
        t = Thread(target=index,args=(f'{i+1}',))
        t.start()

九、事件(Event)

Event()可以创建一个事件管理标志,该标志(event)默认为 False,event 对象主要有 四种方法可以调用:

1、 event.wait(timeout=None):调用该方法的线程会被阻塞,如果设置了 timeout 参数,超时后,线程会停止阻塞继续执行;

2、event.set():将 event 的标志设置为 True,调用 wait 方法的所有线程将被唤 醒;

3、event.clear():将 event 的标志设置为 False,调用 wait 方法的所有线程将被 阻塞;

4、event.is_set():判断 event 的标志是否为 True。

十、线程通信-队列

线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并 行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不 会出现数据污染等意外情况

1使用的队列的好处:

1. 安全

2. 解耦

3. 提高效率

2Queue模块中的常用方法:

Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步

  • Queue.qsize() 返回队列的大小
  • Queue.empty() 如果队列为空,返回True,反之False
  • Queue.full() 如果队列满了,返回True,反之False
  • Queue.full maxsize 大小对应
  • Queue.get([block[, timeout]])获取队列,timeout等待时间
  • Queue.get_nowait() 相当Queue.get(False)
  • Queue.put(item) 写入队列,timeout等待时间
  • Queue.put_nowait(item) 相当Queue.put(item, False)
  • Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
  • Queue.join() 实际上意味着等到队列为空,再执行别的操作

十一、生产者和消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者 彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费 者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列 就相当于一个缓冲区,平衡了生产者和消费者的处理能力。


from threading import Thread
from queue import Queue
from time import sleep
def producer():
    num = 1
    while True:
        print(f'生产了{num}号皮卡丘')
        qe.put(f'{num}号皮卡丘')
        num += 1 
        sleep(1)
def consumer():
    print('购买了{}'.format(qe.get()))
    sleep(2)
if __name__ == "__main__":
    # 共享数据的容器
    qe= Queue(maxsize=5)
    # 创建生产者线程
    t1 = Thread(target = producer)
    # 创建消费者线程
    t2 = Thread(target = consumer)
    # 创建消费者线程
    t3 = Thread(target = consumer)
    # 开始工作
    t1.start()
    t2.start()
    t3.start()

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: python基础之并发编程(一)

本文链接: https://www.lsjlt.com/news/155665.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python基础之并发编程(一)
    目录一、进程(Process)二、线程(Thread)三、并发编程解决方案:四、多线程实现 (两种)1、第一种 函数方法2、第二种 类方法包装五、守护线程与子线程1、线程在分法有:2...
    99+
    2022-11-12
  • python基础之并发编程(二)
    目录一、多进程的实现方法一方法二:二、使用进程的优缺点1、优点2、缺点三、进程的通信1、Queue 实现进程间通信2、Pipe 实现进程间通信(一边发送send(obj),一边接收(...
    99+
    2022-11-12
  • python基础之并发编程(三)
    目录一、协程定义和作用1、使用协程的优点2、使用协程的缺点二、Greenlet 的使用三、Gevent的使用四、async io 异步 IO1、asyncio中的task的使用五、总...
    99+
    2022-11-12
  • python基础之什么是并发编程
    本篇内容介绍了“python基础之什么是并发编程”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、协程定义和作用协程(coroutine),...
    99+
    2023-06-25
  • 详解Java并发编程基础之volatile
    目录一、volatile的定义和实现原理1、Java并发模型采用的方式2、volatile的定义3、volatile的底层实现原理二、volatile的内存语义1、volatile的...
    99+
    2022-11-12
  • Java高并发编程基础之如何使用AQS
    本篇内容主要讲解“Java高并发编程基础之如何使用AQS”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java高并发编程基础之如何使用AQS”吧! 引言曾经有一道比较比较经典的面试题“...
    99+
    2023-06-15
  • Python编程基础之字典
    目录一、字典概念二、字典操作(一)创建字典1、先创建空字典,再添加元素(键值对)2、直接创建包含若干键值对的字典(二)字典操作1、读取字典元素 - 按键取值2、添加字段元素 - 按键...
    99+
    2022-11-12
  • python编程之网络基础
    1 套接字是一种具有通讯端点概念的计算机网络数据结构,网络化的应用程序在开始任何通讯之前都必须要建立套接字。 套接字起源于20世纪70年代,有时人们把套接字成为“伯克利套接字”或“BSD套接字”,期初,套接字被设计用在同一台主机上多个应用...
    99+
    2023-01-31
    基础 网络 python
  • python之基础篇(一)
    防伪码:忘情公子著一、python介绍  python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。  python语法简洁明晰,特色之一是强制用空白符...
    99+
    2023-01-31
    基础 python
  • (1)并发编程实现的基础
    # 多道程序系统 原理,缺点 #允许多个程序同时进入内存并运行。即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬、软件资源。当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序。 # 多道技术中...
    99+
    2023-01-31
    基础
  • 6. `Java` 并发基础之`ReentrantReadLock`
    前言:随着多线程程序的普及,线程同步的问题变得越来越常见。Java中提供了多种同步机制来确保线程安全,其中之一就是ReentrantLock。ReentrantLock是Java中比较常用的一种同...
    99+
    2023-09-21
    java 开发语言
  • Java并发编程之介绍线程安全基础的示例
    这篇文章主要介绍了Java并发编程之介绍线程安全基础的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。线程安全基础线程安全问题账户取款案例同步代码块synchronized...
    99+
    2023-06-06
  • Python基础学习教程:Python基础之基本数据类型(一)
    Python基础学习教程:Python基础之基本数据类型(一)...
    99+
    2023-06-02
  • Python编程基础之类和对象
    目录零、本讲学习目标一、面向对象(一)程序员“面向对象”(二)两种编程思想实现五子棋(三)面向过程 vs. 面向对象 (四)面向对象三大特点1、封装...
    99+
    2022-11-13
  • Python并发编程之协程
    协程介绍 协程:是单线程下的并发,又称微线程,纤程。协程是一种用户态的轻量级线程,即线程是由用户程序自己控制调度的。 需要强调的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫...
    99+
    2023-01-30
    Python
  • Python 编程基础
    数据类型 None 值 整型 浮点型 布尔类型 True,False 字符串 元组 tuple(),有序,不可变 例: t1 = (1,)  t2 = (1,'Hello',1.0,True) 列表 list[],有序,可变 例...
    99+
    2023-01-31
    基础 Python
  • Python基础之pandas数据合并
    一、concat concat函数是在pandas底下的方法,可以将数据根据不同的轴作简单的融合 pd.concat(objs, axis=0, join='outer', join_axes=None...
    99+
    2022-06-02
    Python pandas数据合并 Python pandas
  • python并发编程之多线程编程
    一、threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 二、开启线程的两种方式 方式一: from threading import ...
    99+
    2023-01-31
    之多 线程 python
  • Python基础之元编程知识总结
    目录一、前言二、ImportTime vs RunTime三、元类四、装饰器五、对数据的抽象–描述符六、控制子类的创建——代替元类的方法一、前言 首先说,Python中一切皆对象,老...
    99+
    2022-11-12
  • Python编程基础之输入与输出
    目录一、IPO模型 二、基本输入 - input()函数1、函数格式2、参数说明3、实例演示(1)接收字符串数据(2)接收整型数据(3)接收浮点型数据(4)容易出现的错误三、基本输出...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作