线程

线程


一、线程的介绍

1.解释:线程是操作系统能够调度cpu进行运算的最小单位;线程实际上就是拿一堆指令集合去运算

2.特点:线程之间可以进行数据共享

二、python中的线程

1.限制:因为pythonGUI(全局锁)的缘故,每次python解释器只能接收一个线程,使得多线程的并行效果无法完成,也就是即使有多个cpu,在同一时刻,也只有一个cpu处理一个线程

2.适用:I/O密集型任务或函数(交互型)

三、python中创建线程

1.普通创建

1 import threading
2 t1 = threading.Thread(target=func_name, args=(argument1,))    # 创建线程对象
3 t1.start()    # 启动线程

2.继承式创建

 1 import threading
 2 
 3 class MyThread(threading.Thread):
 4     def __init__(self, num):
 5         threading.Thread.__init__(self)
 6         self.num = num
 7 
 8     def run(self):    # 每个线程的运行逻辑
 9         pass
10 
11 if __name__ == "__main__":
12     t1 = MyThread(1)
13     t1 = MyThread(2)
14 
15     t1.start()
16     t2.start()

四、join和Daemon

join()	# 线程对象的方法,堵塞住主线程,只有当线程对象完成任务之后,主线程才能向下执行
setDaemon(True)	# 线程对象的方法,使得子线程在主线程执行完任务后,自动结束执行。该方法需放在开启线程之前

五、常用方法

Note:

  • 同步锁使得多个线程在执行具有同步锁的内容时,相同同步锁中的内容只能被其中一个线程拿到
threading.current_thread()	# 显示当前执行的线程
threading.active_count()	# 显示当前存在的线程
threading.Lock()	# 获得一个同步锁对象,用来防止同时对一个公共数据进行修改

# Lock示例
L = threading.Lock()
L.acquire()
# 需要加锁的内容(需要避免并发的内容)
L.release()

六、线程、进程的理解

线程	# 就像是一个个的会计员
进程	# 就像是一个会计组织
CPU	 # 就像是一个电脑
函数  # 就像是一份份待统计的数据
pythonGUI  # 限制了一个会计组织只能有一个计算器

线程处理任务	# 就像是会计员拿着一些数据,前往电脑中计算;由于一个会计组织中,有多个会计员,所以一个会计员每次处理的数据和占用电脑的时间都是有限制的,每个会计员需要轮流使用电脑。

六、死锁现象

  1. 形成:获得多把锁对象,在不同的函数中混用锁对象,可能会导致两个线程都在等对方还未释放的锁对象,从而导致两个线程都进入堵塞状态。
  2. 解决方法:使用递归锁(实际上就是可以被多次调用的一个锁对象)
  3. 调用方法:threading.Rlock()

七、信号量

  1. 作用:用来控制每次运行某个任务的线程数量
  2. 创建
import threading
# 参数为线程数量
semaphore = threading.Semaphore()	# or threading.BoundedSemaphore()

# 实例
semaphore.acquire()
# 任务
semaphore.release()

八、条件变量锁

Tips

  • 作用:用来进行线程间的通信
  1. 创建
import threading
# 参数为锁类型,默认为Rlock
lock_con = threading.Condition([lock,Rlock])

# 锁对象的常用方法
acquire()
release()
wait()	     # 调用后,线程会释放锁并进入等待堵塞
notify()	 # 调用后,通知等待池激活一个线程
notifyAll()	 # 调用后,通知等待池激活所有线程

注意:线程被激活后,重新回到加锁那一步

九、同步条件

Tips

  • 作用:用来进行线程间的通信,相当于没有锁的Condition
  1. 创建
event = threading.Event()

# 同步条件对像的常用方法
event.isSet()	# 返回event的状态值
event.wait()	# 如果event.isSet == False将堵塞线程
event.set()		# 设置event的状态值为True,激活阻塞池的所有进程
event.clear()	# 设置event的状态值为False

十、队列

Tips

  • 作用:可以理解为储存数据的容器,每次只允许一个线程存取数据
  1. 创建
# 参数为设定容器大小,不填默认无限大
q = queue.Queue()			# FIFO先进先出
q = queue.LifoQueue()		# LIFO后进先出
q = queue.PriorityQueue()	# 优先级输出

# 队列对象常用方法
q.put()		# 往队列放数据。可设置,block为False,使得队列满时报错;True时是堵塞状态,其他数据不能进入。timeout可定一个超时时间
q.get()		# 往队列取数据
q.size()	# 放回队列大小
q.full()	# 判断队列是否满
q.empty		# 判断队列是否空
posted @ 2021-03-09 12:09  notesForKai  阅读(71)  评论(0编辑  收藏  举报