900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Python 多线程 守护进程 同时运行最大线程数 锁 线程阻塞(线程暂停和继续)

Python 多线程 守护进程 同时运行最大线程数 锁 线程阻塞(线程暂停和继续)

时间:2020-02-02 21:22:18

相关推荐

Python 多线程 守护进程 同时运行最大线程数 锁 线程阻塞(线程暂停和继续)

python 多线程的使用笔记

1、多线程的基本用法

(1)简单任务多线程的开启方式

from threading import Threadimport timedef target(name, n):for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)t1 = Thread(target=target, args=('a', 16, ))t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

(2)自定义复杂任务多线程的开启方式,适合复杂逻辑

from threading import Threadimport timeclass myThread(Thread):def __init__(self, name, n):super(myThread, self).__init__()self.name = nameself.n = ndef run(self):for i in range(0, self.n, 2):print(f'{self.name}_{i}')time.sleep(1)t1 = myThread('a', 16, )t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

2、关于守护线程和join

正常情况下主线程和子线程可以相互没有干扰,独立运行完后程序结束

当我们需要主线程结束后子线程也随着结束,可以将子线程设置为守护线程后,这样主线程结束后,即便子线程没有运行完,子线程也会随着主线程结束

这里注意的是,子线程设置守护线程一定要在子线程开始之前

当我们需要子线程运行完主线程再接着往下运行时,子线程可以调用join()方法, 主线程就会等待,直到子线程终止或者超时才会继续往下执行

这里注意的是,子线程join()一定要在子线程开始之后

jion()里面可以传入timeout参数,超时后主线程会继续往下运行

下面是setDaemo()join()的例子 可以去掉注释看看有什么不同

from threading import Threadimport timedef target(name, n):for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)t1 = Thread(target=target, args=('a', 16,))# t1.setDaemon(True)t1.start()# t1.join()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)

3、关于信号量Semaphore()BoundedSemaphore()

我们可以一次开启很多线程,但是我们想对同时运行的线程控制在一定数量内,开启的线程大于同时运行的线程时,其他的线程就处于阻塞状态,直到有线程运行结束,阻塞的线程才能开始运行,这时我们就用到Semaphore(),

信号量基于内部计数器,初始化Semaphore()时会给计数器一个值,每调用一次acquire(),计数器减1,每调用一次release(), 计数器加1,当计数器为0时,acquire()调用被阻塞

from threading import Thread, Semaphoreimport timesema = Semaphore(3)def target(name, n):sema.acquire()for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)sema.release()sema = Semaphore(3)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

Semaphore()支持上下文,对于上面代码,也可以这样写

from threading import Thread, Semaphoreimport timesema = Semaphore(3)def target(name, n):with sema:for i in range(0, n, 2):print(f'{name}_{i}')time.sleep(1)sema = Semaphore(3)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

BoundedSemaphore继承自Semaphore功能和Semaphore基本一样,只不过BoundedSemaphore有限制,release()时会判断当前信号量的值,如果当前值大于等于初始值,就会抛出错误,而Semaphore并不会抛出异常

4 锁LockRLock

如果运行上面代码,我们会发现,多个子线程之间可能打印在一行上,比较混乱,这是由于线程之间随机调度,同时输出。如果是同时在修改一个变量。或者一个文件,就有可能造成数据错误,这时互斥锁Lock就派上用场了。Lock可以用于锁定资源,Lock有两个基本方法,acquire()release(),调用acquire()状态变为锁定并立即返回,当状态是锁定时,acquire()将阻塞至其他线程调用release()将其改为非锁定状态,然后acquire()调用重置其为锁定状态并返回。锁支持上下文管理协议,即支持with语

from threading import Thread, Lockimport timelock = Lock()def target(name, n):for i in range(0, n, 2):lock.acquire()print(f'{name}_{i}')lock.release()time.sleep(1)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

with语句代替

from threading import Thread, Lockimport timelock = Lock()def target(name, n):for i in range(0, n, 2):with lock:print(f'{name}_{i}')time.sleep(1)for s in 'abcde':Thread(target=target, args=(s, 6,)).start()

如果尝试释放一个非锁定的锁,则会引发RuntimeError异常

RLock被称为重入锁,若要锁定锁,线程调用其acquire()方法;一旦线程拥有了锁,方法将返回。若要解锁,线程调用release()方法。acquire()/release()对可以嵌套,重入锁必须由获取它的线程释放。一旦线程获得了重入锁,同一个线程再次获取它将不阻塞。只有最终release()(最外面一对的release()) 将锁解开,才能让其他线程继续处理acquire()阻塞,线程必须在每次获取它时释放一次。

LockRLock用法大体相同,区别在于Lock在锁定时不属于特定线程,也就是说,Lock可以在一个线程中上锁,在另一个线程中解锁。而对于RLock来说,只有当前线程才能释放本线程上的锁,即解铃还须系铃人。

5Event事件

Event内部定义了一个标志位flag,初始的时候为False,当Flag的值为False,那么event.wait()就会阻塞,当flag值为True,那么event.wait()便不再阻塞Event主要提供以下方法

set()来将其设置为True

clear()将其重新设置为False

is_set()来检查标志位的状态;

wait(timeout=None),会一直监听flag,如果flagFalse就一直处于阻塞状态

from threading import Thread, Eventimport timeclass myThread(Thread):def __init__(self, name, n):super(myThread, self).__init__()self.name = nameself.n = nself.e = Event()def pause(self): # 暂停self.e.clear()def play(self): # 继续self.e.set()def run(self):for i in range(0, self.n, 2):self.e.wait()print(f'{self.name}_{i}')time.sleep(1)t1 = myThread('a', 16, )t1.play()t1.start()for i in range(1, 11, 2):print(f'主线程_{i}')time.sleep(1)if i == 3:t1.pause() # 子线程暂停if i == 7:t1.play() # 子线程继续

特别感谢下面两篇文章的作者,供大家做参考学习

python多线程详解(超详细)

python threading模块的Lock和RLock区别

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。