线程、守护线程、线程锁、递归锁、死锁、队列

本文深入探讨了Python中线程的基本概念与使用方法,包括线程创建、守护线程、线程锁、单例模式、递归锁、死锁现象及解决策略,以及队列在多线程环境中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程


from threading import Thread
import time


def fun(i):
    print(f'start{i}')
    time.sleep(1)
    print(f'end{i}')

for i in range(10):
    Thread(target=fun,args=(i,)).start()

守护线程


import time
from threading import Thread

def fun():
    while True:
        # time.sleep(0.5)
        print("in one")
        time.sleep(1)

def fun2():
    print("in two")

t = Thread(target=fun)
t.daemon = True     #守护线程
t.start()

Thread(target=fun2).start()   #加此代码后,通过运行结果可以看得出来,守护线程会主线程结束后继续守护其他子线程

#主线程会等待子线程结束之后才结束
###其他子线程--》主线程结束---》主进程结束---》整个进程中所有的资源都被回收---》守护线程也会别回收

线程锁

from threading import Thread


n = 0
def fun1():
    for i in range(20000):
        global n
        n += 1

def fun2():
    for i in range(20000):
        global n
        n -= 1

t_1 = []
for i in range(2):
    t1 = Thread(target=fun1)
    t1.start()
    t2 = Thread(target=fun1)
    t2.start()
    t_1.append(t1)
    t_1.append(t2)
for t in t_1:
    t.join()

运行结果:
在这里插入图片描述

## (配置高的电脑,运行快比较容易出现错误)有打印结果可以看得出来,线程之间也存在数据不安全。
## += -= *= /= while if 等数据不安全
## append pop 数据安全,列表中的方法或者字典中的方法去操作全局变量的时候,数据是安全的

import dis
#关于dis介绍 https://blog.csdn.net/weixin_42233629/article/details/82848315
a = 0
def fun():
    global a
    print(a)

dis.dis(fun)

在这里插入图片描述

from threading import Thread
import time

n = []
def fun1():
    for i in range(20000):
        n.append(1)

def fun2():
    for i in range(20000):
        if not n:
            time.sleep(0.000001)
        n.pop()

t_1 = []
for i in range(2):
    t1 = Thread(target=fun1)
    t1.start()
    t2 = Thread(target=fun1)
    t2.start()
    t_1.append(t1)
    t_1.append(t2)
for t in t_1:
    t.join()

+ 会遇到再执行pop的时候,列表里面没有数值,报错

### 加锁
from threading import Thread,Lock


n = 0
def fun1(lock):
    for i in range(20000):
        global n
        while lock:
            n += 1

def fun2(lock):
    for i in range(20000):
        global n
        while lock:
            n -= 1

t_1 = []
lock = Lock()
for i in range(2):
    t1 = Thread(target=fun1,args=(lock,))
    t1.start()
    t2 = Thread(target=fun1,args=(lock,))
    t2.start()
    t_1.append(t1)
    t_1.append(t2)
for t in t_1:
    t.join()

在这里插入图片描述

# 单例模式  
#单例讲解 https://www.cnblogs.com/onefine/p/10499386.html

import time

class A():
    from threading import Lock
    __instance = None
    lock = Lock()
    def __new__(cls, *args, **kwargs):
        with cls.lock:
            if not cls.__instance:
                time.sleep(0.000001)   #cpu轮转
                cls.__instance = super.__new__(cls)
        return cls.__instance

def func():
    a = A()
    print(a)
from threading import Thread
for i in range(10):
    Thread(target=func()).start()

#不会线程锁 不要操作全局变量,不要在类里面操作静态变量

#####递归所
from threading import RLock,Lock
#lock:互斥锁:效率高
#Rlock:递归所:效率低


# l = Lock()
# l.acquire()
# l.acquire()
# print('锁住了')
# l.release()

l1 = RLock()
l1.acquire()   #与互斥锁的区别,在同一个线程中可以被acquire()多次,但是同时需要release()相同次数
l1.acquire()
print('锁住了1')
l1.release()
l1.release()

#锁死
#产生现象:多把锁,并在多个线程中交叉使用(与互斥锁和递归锁没有关系)
# 例如:
import time
from threading import Thread,Lock,RLock

t1 = Lock()
t2 = Lock()

def eat(name):
    t1.acquire()
    print(name,'面')
    t2.acquire()
    print(name,'叉子')
    print('吃面')
    time.sleep(0.1)
    t2.release()
    print('放下叉子')
    t1.release()
    print('放下面')

def eat1(name):
    t2.acquire()
    print(name,'叉子')
    t1.acquire()
    print(name,'面')
    print('吃面')
    time.sleep(0.1)
    t1.release()
    print('放下面')
    t2.release()
    print('放下叉子')


Thread(target=eat,args=('test1',)).start()
Thread(target=eat1,args=('test2',)).start()
Thread(target=eat,args=('test3',)).start()
Thread(target=eat1,args=('test4',)).start()

##如果互斥锁,出现了死锁现象,最快的解决方案就是把所有的互斥锁都改成一把递归所,但是效率降低了

import time
from threading import Thread,Lock,RLock

t1 = t2 = RLock()


def eat(name):
    t1.acquire()
    print(name,'面')
    t2.acquire()
    print(name,'叉子')
    print(name,'吃面')
    time.sleep(0.1)
    t2.release()
    print(name,'放下叉子')
    t1.release()
    print(name,'放下面')

def eat1(name):
    t2.acquire()
    print(name,'叉子')
    t1.acquire()
    print(name,'面')
    print(name,'吃面')
    time.sleep(0.1)
    t1.release()
    print(name,'放下面')
    t2.release()
    print(name,'放下叉子')


Thread(target=eat,args=('test1',)).start()
Thread(target=eat1,args=('test2',)).start()
Thread(target=eat,args=('test3',)).start()
Thread(target=eat1,args=('test4',)).start()

##互斥锁解决死锁
import time
from threading import Thread,Lock,RLock

t1t2 = Lock()


def eat(name):
    t1t2.acquire()
    print(name,'面')
    print(name,'叉子')
    print(name,'吃面')
    time.sleep(0.1)
    t1t2.release()
    print(name,'放下叉子')
    print(name,'放下面')

def eat1(name):
    t1t2.acquire()
    print(name,'叉子')
    print(name,'面')
    print(name,'吃面')
    time.sleep(0.1)
    t1t2.release()
    print(name,'放下面')
    print(name,'放下叉子')


Thread(target=eat,args=('test1',)).start()
Thread(target=eat1,args=('test2',)).start()
Thread(target=eat,args=('test3',)).start()
Thread(target=eat1,args=('test4',)).start()

队列


#先进先出
from queue import Queue

q = Queue()
q.put(2)
q.put(1)
a = q.get()
b = q.get()
print(a,b)

#结果
# 2 1

#
# from queue import Empty  #fifo 先进先出的队列
# q = Queue(4)
# q.put(1)
# q.put(2)
# q.put(3)
# q.put(4)
# try:
#     q.get_nowait()
# except Empty:
#     pass

#后进先出
from queue import LifoQueue

q = LifoQueue()
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())

#结果
# 3
# 2
# 1


#优先级队列
from queue import PriorityQueue

q = PriorityQueue()
q.put((0,'A'))    #根据ASCII值从小到大优先输出
q.put((1,'B'))
q.put((2,'C'))
print(q.get())
print(q.get())
print(q.get())

#结果
# (0, 'A')
# (1, 'B')
# (2, 'C')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值