多线程原理

线程处理IO密集型任务

import threading
import time
def foo(something):
    print(something)
    time.sleep(1)

begin_time = time.time()
'''
#
总消耗时长: 2.001000165939331
foo("磁盘写入100M数据")
foo("cpu去做其他事情")
'''

'''
#总消耗时长: 0.0010004043579101562
#创建线程实例
t1 = threading.Thread(target=foo,args=("磁盘写入100M数据",))
t2 = threading.Thread(target=foo,args=("cpu去做其他事情",))
#启动线程
t1.start()
t2.start()
'''

'''
#总消耗时长:  1.001000165939331
#创建线程实例
t1 = threading.Thread(target=foo,args=("磁盘写入100M数据",))
t2 = threading.Thread(target=foo,args=("cpu去做其他事情",))
#启动线程
t1.start()
t2.start()
#在子线程完成运行之前,这个子线程的主线程一直被阻塞
t1.join()
t2.join()  #可以只有一个join
'''
end_time = time.time()
print("总消耗时长:",end_time-begin_time)

线程处理计算密集型任务

import threading
import time
def foo():
    num = 0
    for i in range(10000000):
        num = num + i

begin_time = time.time()
'''
#
串行 总消耗时长:1.819000005722046
foo()
foo()
'''

'''
#并发 总消耗时长:1.7979998588562012
t1 = threading.Thread(target=foo)
t2 = threading.Thread(target=foo)

t1.start()
t2.start()

t1.join()
t2.join()
'''
end_time = time.time()
print("总消耗时长:",end_time-begin_time)

join的功能

 

输出:

这是最后一行代码

3s后

阳光明媚

阻塞线程:

输出:

阳光明媚

3s后

这是最后一行代码

守护线程

import threading
import time

a = []
def foo():
    while True:
        a.append("1")
        print("产生了一个数据")
        time.sleep(1)
t = threading.Thread(target=foo)
#设置守护线程,必须在start之前
#作用就是在主线程想要提出进程的时候,不需要等待自己结束,直接退出就行
t.setDaemon(True)
t.start()
for i in range(5):
    if a:
        a.remove("1")
        print("消耗了一个数据")
        time.sleep(1)

print("不再需要消耗数据了")

输出:

 

不安全的开发

无锁:

import threading
import time
balance = 500 #账户余额
#操作账户余额
def foo(num):
    #声明全局变量
   
global balance
    #把接口获取到的值放进自己的变量系统
   
user_balance = balance
    time.sleep(1) #防止代码太少,cpu执行速度过快,造成串行
    #计算出结果
   
user_balance = user_balance + num
    #将结果通过接口传递出去
   
balance = user_balance
#消费300元
t1 = threading.Thread(target=foo,args=[-300])
#收入10000元
t2 = threading.Thread(target=foo,args=[10000])
t1.start()
t2.start()
t1.join()
t2.join()
print("账户余额:",balance)   #值不稳定,200或10500随机出现

上锁:

import threading
import time
balance = 500 #账户余额
r = threading.Lock()  #声明一把锁
'''
这是一把同步锁
同步锁必须 上锁 解锁 相对
如果上锁后,不解锁,再次上锁,代码会阻塞
如果解锁后,不上锁,又进行解锁,代码会报错
'''
#操作账户余额
def foo(num):
    #声明全局变量
   global balance
    #上锁
   
r.acquire()   
    #把接口获取到的值放进自己的变量系统
   
user_balance = balance
    time.sleep(1) #防止代码太少,cpu执行速度过快,造成串行
    #计算出结果
   
user_balance = user_balance + num
    #将结果通过接口传递出去
   
balance = user_balance
    #解锁
   
r.release()
#消费300元
t1 = threading.Thread(target=foo,args=[-300])
#收入10000元
t2 = threading.Thread(target=foo,args=[10000])
t1.start()
t2.start()
t1.join()
t2.join()
print("账户余额:",balance)   #10200

死锁

import threading
import time
lockA = threading.Lock()   #面试官的锁
lockB = threading.Lock()   #小明的锁
#面试官
def foo1():
    lockA.acquire() #上锁
   
print("请解释什么是死锁")
    time.sleep(1)
    lockB.acquire()  #上锁
   
print("发 offer")
    time.sleep(1)
    lockA.release()  #释放锁
   
lockB.release()  #释放锁
#小明
def foo2():
    lockB.acquire()  # 上锁
   
print("请给我 offer")
    time.sleep(1)
    lockA.acquire()  # 上锁
   
print("解释了什么是死锁")
    time.sleep(1)
    lockA.release()  # 释放锁
   
lockB.release()  # 释放锁
t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)
t1.start()
t2.start()
t1.join()
t2.join()

输出:

递归锁

import threading
import time
# lockA = threading.Lock()   #面试官的锁
# lockB = threading.Lock()   #小明的锁
lockR = threading.RLock() #递归锁
'''
递归锁内部维护着一把锁和一个计算器
每次上锁:计数器加1
每次解锁:计数器减1
计数器可以大于0,也可以等于0,但不能小于0
'''
#面试官
def foo1():
    lockR.acquire() #上锁
   
print("请解释什么是死锁")
    time.sleep(1)
    lockR.acquire()  #上锁
   
print("发 offer")
    time.sleep(1)
    lockR.release()  #释放锁
   
lockR.release()  #释放锁
#小明
def foo2():
    lockR.acquire()  # 上锁
   
print("请给我 offer")
    time.sleep(1)
    lockR.acquire()  # 上锁
   
print("解释了什么是死锁")
    time.sleep(1)
    lockR.release()  # 释放锁
   
lockR.release()  # 释放锁
t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)
t1.start()
t2.start()
t1.join()
t2.join()

输出:

 

猜你喜欢

转载自www.cnblogs.com/like1824/p/12891214.html