栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python并发编程笔记4

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python并发编程笔记4

python并发编程笔记4

是根据蚂蚁学Python的视频做的笔记,方便自己后续回顾

视频链接:BV1bK411A7tV

老师的源码

这一份笔记对应的是视频的P6

文章目录
  • python并发编程笔记4
  • P6-Python线程安全问题以及解决方案
    • 1、线程安全概念介绍
    • 2、Lock用于解决线程安全问题
      • 2.1、try-finally模式
      • 2.2、with模式
    • 3、实例代码演示问题以及解决方案
      • 3.1、随机可能出错版本:
      • 3.2、一定出问题(添加sleep语句):
      • 3.3、解决方案:with模式

P6-Python线程安全问题以及解决方案 1、线程安全概念介绍

线程安全:指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。

线程不安全:由于线程的执行随时会发生切换,就造成了不可预料的结果,出现线程不安全

如下图:i代码是没有问题的,但如果if语句判断完,发生线程切换,就会造成错误

2、Lock用于解决线程安全问题 2.1、try-finally模式
import threading

# 获取lock对象
lock = threading.Lock()

# 获取这个锁
lock.acquire()
try:
    # do something
finally:
    # 释放锁
    lock.release()
2.2、with模式
import threading

lock = threading.Lock()

with:
    # do something

把代码放到lock里面,就不会出现上述提到的取钱扣多钱的问题

3、实例代码演示问题以及解决方案 3.1、随机可能出错版本:
# 03lock_concurrent.py

import threading


# 创建一个账号类
class Account:
    def __init__(self, balance):
        self.balance = balance


# 取钱函数
def draw(account, amount):
    if account.balance >= amount:
        print(threading.current_thread().name,
              "取钱成功")
        account.balance -= amount
        print(threading.current_thread().name,
              "余额", account.balance)
    else:
        print(threading.current_thread().name,
              "取钱失败,余额不足")


if __name__ == '__main__':
    # 实例账号对象,1000元进账户
    account = Account(1000)
    # 实例俩个线程对象
    ta = threading.Thread(name="ta", target=draw, args=(account, 800))
    tb = threading.Thread(name="tb", target=draw, args=(account, 800))
    # 启动两个线程对象
    ta.start()
    tb.start()
3.2、一定出问题(添加sleep语句):

sleep语句一定会导致当前线程阻塞,阻塞就会切换线程

# 03lock_concurrent.py

import threading
import time


# 创建一个账号类
class Account:
    def __init__(self, balance):
        self.balance = balance


# 取钱函数
def draw(account, amount):
    if account.balance >= amount:
        # sleep语句一定会导致当前线程阻塞,阻塞就会切换线程
        time.sleep(0.1)
        print(threading.current_thread().name,
              "取钱成功")
        account.balance -= amount
        print(threading.current_thread().name,
              "余额", account.balance)
    else:
        print(threading.current_thread().name,
              "取钱失败,余额不足")


if __name__ == '__main__':
    # 实例账号对象,1000元进账户
    account = Account(1000)
    # 实例俩个线程对象
    ta = threading.Thread(name="ta", target=draw, args=(account, 800))
    tb = threading.Thread(name="tb", target=draw, args=(account, 800))
    # 启动两个线程对象
    ta.start()
    tb.start()
3.3、解决方案:with模式

在类上添加lock = threading.Lock(),并将draw函数嵌入with中

# 03lock_concurrent.py

import threading
import time

lock = threading.Lock()


# 创建一个账号类
class Account:
    def __init__(self, balance):
        self.balance = balance


# 取钱函数
def draw(account, amount):
    with lock:
        if account.balance >= amount:
            # sleep语句一定会导致当前线程阻塞,阻塞就会切换线程
            time.sleep(0.1)
            print(threading.current_thread().name,
                  "取钱成功")
            account.balance -= amount
            print(threading.current_thread().name,
                  "余额", account.balance)
        else:
            print(threading.current_thread().name,
                  "取钱失败,余额不足")


if __name__ == '__main__':
    # 实例账号对象,1000元进账户
    account = Account(1000)
    # 实例俩个线程对象
    ta = threading.Thread(name="ta", target=draw, args=(account, 800))
    tb = threading.Thread(name="tb", target=draw, args=(account, 800))
    # 启动两个线程对象
    ta.start()
    tb.start()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/875548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号