天天看点

python锁简单举例

代码通过系统调用,请求OS分配一个新的线程

python里面:

thread与threading都可以用来创建管理线程,thread比较底层,threading是thread模块的扩展,提供了很多线程同步功能,使用起来更加方便强大。

这个target 可以是函数或是类的方法

子线程执行完入口函数后, 就停止了。 (生命周期就在这个入口函数里。)

#在执行到t1.start()时会启动一个新线程, 这个线程和主线程同时执行。
print('main thread start.')
import threading
from time import sleep

def Thread_entry():
    print('child thread 1 , start')
    sleep(15)
    print('child thread 1, end')

t1 = threading.Thread(target=Thread_entry)  #实例化类Thread, 并指定线程执行的入口
t1.start() #启动线程
sleep(10)
print('main thread end.')

输出:
main thread start.
child thread 1 , start
main thread end.
child thread 1, end
           

threading.Thread只是创建线程对象

start才是创建

join的作用 #主线程要等子线程结束 t1.join()

锁举例:如果这个例子不用锁,很有可能两个线程得到的余额都是2000,然后都是在2000上操作,最后的余额可能是2010或是1990

import threading
from time import sleep

zhifubao = {'lucy': 2000} #公共变量,lucy的支付宝有2000元
#线程调用公共变量,都在线程内维护一份copy,如果多个线程同时获取到同一个公共变量并对其修改,会出错。 
#调用Lock函数,返回一个锁对象。
zhifubao_lock = threading.Lock()

def thread1_didi_pay(account, amount):
    #如果是局部变量,多个线程不会将其搞混乱的。因为每个线程都 
    #在代码访问共享对象之前加锁,当有多个线程同时执行lock.acquired()时,只有一个线程能成功的获取锁,然后继续执行代码,
    # 其他线程继续等待,直到获得锁为止。 
    zhifubao_lock.acquire()
    print('t1, get balace from bank.')
    balance = zhifubao['lucy']
    zhifubao['lucy'] = balance - amount
    #访问完共享对象,释放锁
    #访问结束后,一定要调用lock对象的realese方法,进行解锁操作。否则其它等待的线程将永远等待下去,成为死线程。
    zhifubao_lock.release()

def thread1_yuebao_interst(account,amount):
    #访问共享对象前加锁
    zhifubao_lock.acquire()
    print('t1, get balace from bank.')
    balance = zhifubao['lucy']
    zhifubao['lucy'] = balance + amount
    #释放锁
    zhifubao_lock.release()

#此时,并不关心哪个线程先调用。
t1 = threading.Thread(target=thread1_didi_pay,args=(zhifubao['lucy'],10))
t2 = threading.Thread(target=thread1_yuebao_interst,args=('zhifubao[lucy]',10))
t1.start()
t2.start()
t1.join()
t2.join()
print(zhifubao)