一、互斥锁:
1.线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。
2.互斥锁为资源引入一个状态:锁定、非锁定
3.某个线程要更改共享数据是,先将其锁定。此时资源的状态为锁定,其他线程不能更改知道该
线程释放资源,将资源的状态编程"非锁定",其他的线程才能再次锁定该资源
4.互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
例子:
创建锁
suo = threading.LOck()
锁定
suo.acquire()
非锁定释放
suo.release()
例子:
import threading
count = 0
def line1():
"""
函数1
:return:
"""
global count
global lock
for i in range(100000):
lock.acquire()
count += 1
lock.release()
def line2():
"""
函数2
:return:
"""
global count
global lock
for i in range(100000):
lock.acquire()
count += 1
lock.release()
lock = threading.Lock() # 创建锁
thread1 = threading.Thread(target=line1) # 创建线程
thread2 = threading.Thread(target=line1) # 创建线程
thread1.start() # 线程开始
thread2.start() # 线程开始
thread1.join() # 阻塞线程
thread2.join() # 阻塞线程
print(count)
二、死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会
造成死锁‘尽管死锁很少发生,但一旦发生就会造成应用的停止响应。
三、GIL 全局解释器锁:、
因为全局解释器锁的原因,保证了python在运行的时候一次只能运行一个线程,而做不到线程
的并行,一个线程执行完了才能接着执行下一线程。(线程只能并发不能并行)
我们可以使用多进程来实现程序的并行。
问题一: python单线程和多线程分别来完成工作,到底那个快?
1.io密集型:涉及到网络、磁盘io的任务都是io密集型任务,这类任务的特点是cpu消耗很少,任务的大部分的
时间都在等待io操作完成(因为io的速度远远低于cpu和内训的速度)
结论:io密集型操作,多线程比单线程要快
2.cpu密集型:cpu密集型也称为计算密集型,任务的特点是要进行大量的计算,消耗cpu资源,比如
计算圆周率、对视频进行高清解码等等,全靠cpu的运算能力
结论:cpu密集型操作,单线程比多线程要快
四、队列
1.Python的Queue模块中提供了同步的、线程安全的队列,这些队列都实现了锁原语,能够在多线程中直接
使用。可以使用队列来实现线程间的同步。
2.初始化Queue()对象时,若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可
接受的消息数量没有上限。
队列的方法:
task_done()在队列中每获取一个数据,就要发送一个标记
join()判断队列中的任务是否执行完毕,如果没有执行完毕,会一直等待。
qsize()返回当前队列包含的消息数量;
empty()判断队列是否为空 ,返回True 或 False
full()判断队列是否为满了 ,返回True 或 False
put()添加队列,如果队列数据达到上限,就不能再添加。
get()获取队列,如果队列数据为空,就不能在获取
put_nowait()添加队列不等待
get_nowait()获取队列不等待
1.FIFO(先入先出)队列
from queue import Queue
2.LIFO后入先出
from queue import LifoQueue
3.优先级队列 PriorityQueue
from queue import PriorityQueue
优先级队列,以优先级顺序(最低优先级)检索打开条目的队列的变体。
条目通常是表单的元组:(优先number, data)
注意:这三个模块都有上面九个方法