python并行编程(2)---线程安全问题

并行编程2

  • 线程安全介绍
  • Lock加锁
    • 加锁写法1
    • 加锁写法2
    • 枷锁代码实现并对比

线程安全介绍

线程安全指某个函数,函数库在多线程环境中被调用时,能够正确的处理多线程之间的共享变量,是程序功能正确完成
线程的执行随时发生切换,会使线程不安全。比如两个线程都在完成同一个变量count的相减
python并行编程(2)---线程安全问题_第1张图片

Lock加锁

枷锁可以解决线程安全的问题

加锁写法1

import threading

lock=threading.Lock()

lock.acquire()
try:
	#do something
finally:
	lock.release()

加锁写法2

import threading

lock=threading.Lock()

lock.acquire()
with lock:
	#do something

枷锁代码实现并对比

  • 算例1
# -*- coding: utf-8 -*-
"""
Created on Tue May  4 13:22:21 2021

@author: hellohaojun
"""

import threading
import time
class Account:
    def __init__(self,balance):
        self.balance=balance
        

def darw(account,amount):
    if account.balance>=amount:
    	#time.sleep(0.1)
        print(threading.currentThread().name,"取钱成功")
        account.balance-=amount
        print(threading.currentThread().name,"余额",account.balance) 
    
    else:
        print(threading.currentThread().name,"取钱失败,余额不足")

if __name__=="__main__":
    account=Account(1000)
    ta=threading.Thread(name="ta",target=darw,args=[account,800])
    tb=threading.Thread(name="tb",target=darw,args=[account,800])
    
    ta.start()
    tb.start()
    

以上例子开了两个线程,两个线程都是减去amount,这是如果线程1完成之后在进行线程2,是正确的。但是如果进了线程1之后,还没完成减法就进入了线程2,那么这个时候线程2的if语句也满足,那么两个线程中相减的语句一就都会进行,就会造成错误。

  1. 结果1
    理想的结果
ta 取钱成功
ta 余额 200
tb 取钱失败,余额不足
  1. 结果2
    这就是线程互串的结果
tatb 取钱成功
ta 余额 200
 取钱成功
tb 余额 -600
  • 算例2
    与算例1相比,在if循环体里边加上一个短暂的延时,这样线程a就会停滞一会,这个时候线程2也进来了。然后就会造成错误,因为开一个线程的时间小于0.1秒。
  1. 结果
tatb 取钱成功
ta 余额 200
 取钱成功
tb 余额 -600
  • 算例3
    在算例2的基础上加上lock,就是在一个线程结束之前,其他线程无法进入;
# -*- coding: utf-8 -*-
"""
Created on Tue May  4 13:22:21 2021

@author: hellohaojun
"""

import threading
import time

lock=threading.Lock()//锁的实例化

class Account:
    def __init__(self,balance):
        self.balance=balance
        

def darw(account,amount):
    with lock:
        if account.balance>=amount:
            time.sleep(0.1)
            print(threading.currentThread().name,"取钱成功")
            account.balance-=amount
            print(threading.currentThread().name,"余额",account.balance) 
        
        else:
            print(threading.currentThread().name,"取钱失败,余额不足")

if __name__=="__main__":
    account=Account(1000)
    ta=threading.Thread(name="ta",target=darw,args=[account,800])
    tb=threading.Thread(name="tb",target=darw,args=[account,800])
    
    ta.start()
    tb.start()
       
  • 结果
ta 取钱成功
ta 余额 200
tb 取钱失败,余额不足
` ``

你可能感兴趣的:(python,python,多线程,thread)