python-多线程编程(二)- 守护线程、线程锁

本文介绍了Python中守护线程的使用,通过示例展示了即使守护线程设置为True,它也会等待非守护线程结束后才结束。此外,讨论了线程锁和递归锁的概念,以解决并发执行时可能出现的死锁问题,并通过吃面问题举例说明了递归锁如何避免死锁。
摘要由CSDN通过智能技术生成

一、守护线程

守护线程的使用方法和守护进程类似,也是deamon=True的方式来启动一个守护线程,但是具体的执行结果和守护进程略有不同。

from threading import Thread
from time import sleep

def func1():
    while True:
        print("$$$$$")
        sleep(2)


def func2():
    sleep(6)
    print("子线程运行结束")


t1 = Thread(target=func1)
t1.daemon = True
t1.start()
t2 = Thread(target=func2)
t2.start()
print("主线程")

----------------
$$$$$
主线程
$$$$$
$$$$$
子线程运行结束

这个例子当中,t1为守护线程,如果按照守护进程的定义,子线程会随着主线程的运行结束而结束,那么t1也应该随着主线程的运行结束而结束,但实际运行结果是t1随着t2的结束才结束。

那这是为什么呢?

实际上主进程会随着主线程的结束,回收进程的资源。

  • 主进程结束时会把守护进程进行回收,因此守护进程会随着主进程的结束而结束,再等待不是守护进程的进程结束进行回收,不然会产生僵尸进程。
  • 而主线程必须等待所有的线程结束之后才算结束,不然会导致所有资源被回收,因此守护线程会在主线程代码结束之后继续运行。

二、线程锁

线程之间用锁的情况比进程之间会多很多,因为进程之前数据的安全性比线程高很多。

而线程之间用锁,我们会遇到一个死锁的问题,经典的一个问题就吃面问题。

我们假设三个人A、B、C围着一张桌子吃面,要吃到面,必须要同时拿到叉子和面,那为了保证不会有三个人同时吃面的问题,只有一把叉子和一碗面,那么就如同三个线程和两把锁,只有同时拿到两把锁,才可以进行代码的运行。

那会遇到这么一种情况,A拿到了叉子,B抢到了面,但是由于谁都不满足吃面的条件,他们也不把叉子和面换回去,因此就僵持住了。就像两把锁都没有释放,这就是死锁的问题。

递归锁

而解决这种问题的这种方式就是递归锁,递归锁的机制就是你必须先拿到锁A,才能拿锁B,之后拿锁C,以此递进。而释放锁的时候,是反过来的一个过程,我们用一个代码的例子来看看,就是上面的吃面的问题。

from threading import Thread,RLock

food_lock = fork_lock = RLock() #递归锁

def eat(name):
    food_lock.acquire()
    print("拿到食物了")
    fork_lock.acquire()
    print("拿到叉子了")
    print("%s开吃"%name)
    food_lock.release()
    fork_lock.release()


def eat2(name):
    food_lock.acquire()
    print("拿到食物了")
    fork_lock.acquire()
    print("拿到叉子了")
    print("%s开吃"%name)
    food_lock.release()
    fork_lock.release()

t1 = Thread(target=eat,args=("lufei",))
t2 = Thread(target=eat2,args=("zuoluo",))
t3 = Thread(target=eat,args=("naridou",))
t4 = Thread(target=eat2,args=("sasigai",))
t1.start()
t2.start()
t3.start()
t4.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值