python 多线程 锁 概念

我对锁的理解:

        锁 即是对资源的一种占有,锁的是资源而不是线程。

        一条线程在使用某项资源时,获取了锁,那么此时 锁 的状态就是锁住的。如果在该线程未释放锁时,其他线程就无法获取锁,也就无法使用资源。

        用下面一段程序在简单解释一下:

        

import threading
import logging
import time

total = 0
lock = threading.Lock()


def get_logger():
    logger = logging.getLogger("threading_eg")
    logger.setLevel(logging.DEBUG)
    fh = logging.FileHandler("C:\\Users\Administrator\Desktop\\test\\threading.log")
    fmt = '%(asctime)s - %(name)s - %(threadName)s - %(message)s'
    formatter = logging.Formatter(fmt)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger


def plus_total(amount, logger):
    global total
    logger.debug('lock not acquire')
    lock.acquire()
    logger.debug('lock has acquire')
    total += amount
    print(total)
    lock.release()


def m_total(amount, logger):
    global total
    lock.acquire()
    total -= amount
    print(total)
    logger.debug('lock not released')
    time.sleep(10)
    lock.release()
    logger.debug('lock has released')


logger = get_logger()
my_thread1 = threading.Thread(
    target=m_total, args=(5, logger))
my_thread2 = threading.Thread(
    target=plus_total, args=(5, logger))

logger.debug('thread1 start')
my_thread1.start()
time.sleep(3)
logger.debug('thread2 start')
my_thread2.start()

第一个函数不用说,日志记录

第二个函数将一个全局变量加5后输出,第三个函数将一个全局变量减5后输出。在每个函数执行的第一行都需要获取锁,在第三个函数获取锁后,等待10s再释放锁。

在主程序中,先构造了一个logger对象,然后构造了两个线程,第一个线程启动后等待3s再启动启动第二个线程。

看结果:


在主线程中首先线程1启动,线程1在很短时间内执行完了m_total函数大部分,直到sleep需要等待10s,3s后线程2启动,而此时锁还未被释放,所以线程2无法执行plus_total中的加法内容。过了10s后,线程1将锁释放,此时线程2也获得了锁,可以执行加法内容了。

这里就充分体现了锁的作用。

lock是一个低级的锁,即同一线程无法多次获得锁。为了解决这个方法,可以利用 重入锁 Rlock,同一线程可以多次获取该,。该线程也必须释放相同次数该锁。

也就是说,Rlock内部有一个计数器,当值为0时处于未锁定状态,当acquire时值+1,release时值-1。

看下面这段程序:

import threading
import logging

total = 0
lock = threading.Lock()


def get_logger():
    logger = logging.getLogger("threading_eg")
    logger.setLevel(logging.DEBUG)
    fh = logging.FileHandler("C:\\Users\Administrator\Desktop\\test\\threading2.log")
    fmt = '%(asctime)s - %(name)s - %(threadName)s - %(message)s'
    formatter = logging.Formatter(fmt)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger


def plus_total(amount, logger):
    global total
    logger.debug('lock not acquire')
    lock.acquire()
    logger.debug('lock has acquire')
    total += amount
    print(total)
    lock.release()


def m_total(amount, logger):
    global total
    lock.acquire()
    logger.debug('lock has acquire')
    total -= amount
    print(total)
    logger.debug('lock not released')


logger = get_logger()
m_total(5, logger)
plus_total(5, logger)

大体上没有什么改变,在主线程里同时调用了两个函数,而m_total在获取锁之后没有释放,所以plus_total无法完成。这段程序也因此是一直停滞,无法完成。

结果:可以看出主线程的plus_total一直没有获取锁


接下来将锁改为RLock:

lock = threading.RLock()

执行后结果如下:


虽然m_total没有释放锁,但是plus_total同样获取了锁。这就是RLock的特性,即同一线程可以多次获取该锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值