线程
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')