[Language]Python的多线程
来源:互联网 发布:开淘宝网店怎样发货 编辑:程序博客网 时间:2024/06/05 07:24
简述
多线程设计在系统中是比较关键的部分,对于系统性能的提高以及一个较为复杂框架的构建都是很重要的。
进程与线程差别
这部分许多资料可供参考,比如一些动画介绍,还有CSAPP书中也详细讲到。在嵌入式系统中一般是没有进程和线程区分概念的,因为嵌入式系统就跑一个程序(一个main入口),通过RTOS管理其中的各个线程(一般称为task),其实总的就一个进程,可以独享嵌入式系统的Flash, RAM等资源,也不会有IPC等技术和概念。
在多用户操作系统,一般非RTOS就是吧,Linux, Windows, Android, MacOS, IOS,上面是会有许许多多的程序可以同时被运行,最后被终止的。一个程序其实就是一段二进制代码,放在这些计算机的存储器上,只有这个程序被加载并执行,此时就有针对这个程序的生命周期和进程概念了,因此其实进程指的是程序的一次执行,进程有其独立的内存、栈、地址空间等,进程间通信需要用IPC进行进程间通信。
Python中的线程
Python设计之初的考虑是在Python解释器主循环中同时只有一个线程在执行,即Python解释器可以运行多个线程,但是任意时刻只有一个线程在解释器中运行。而做到这一点是通过Python的Global Interpreter Lock-GIL来实现的:
Python解释器使用GIL控制线程执行首先设置GIL,并切换到一个线程去执行然后运行指定数量的字节码指令,或者线程主动让出控制把线程设置为睡眠状态,并解锁GIL
Python多线程编程-threading模块
目前需要在Python代码中使用多线程设计,都是import threading moduel。目前Python的线程没有优先级区分,也没有线程组,线程不可销毁、停止、挂起、恢复或中断。
threading module的方法
threading module的常数
threading module的Thread类(对象)
Thread类是可以单独控制和运行的线程,可以通过传递一个可调用对象给构造器,或者重写子类的run()方法来指定线程的运作。线程对象被创建,就必须通过start()方法来开始运作,此时会调用其run()方法,线程就激活了。直到run()方法终止,线程就停止。
其他线程可以调用本线程的join()方法,此时调用本线程join()方法的线程会阻塞,等待本线程执行结束退出,再继续调用线程的后续执行。
线程也可以标识为daemon线程,在Python程序退出时,daemon线程仍然保留,知道关机时才会退出。
还有一种main线程,即开始运行Python程序的线程,为非daemon线程。
还有dummy线程,这种线程是在threading module之外开启,比如通过调用的C代码创建的线程。
threading module的Lock类(对象)
Lock即primitive lock,原始锁,只会处于两个状态中的一个,“locked”(初始态)或“unlocked”。并有acquire()和release()两个方法。acquire()有阻塞和非阻塞两种方式,阻塞是会一直等待直到锁释放,而非阻塞是如果获取不到锁就立即返回false。相关图示如下:
threading module的RLock类(对象)
Reentrant Lock,可重入锁,即对于同一线程而言,是可重入锁,而对于其他线程而言,和上面的Lock没有区别。
和Lock的区别在于:在某一线程acquire()一个lock时,发现lock已经被本线程之前acquire()过但还未release(),此时可以继续acquire(),只是要进行同样次数的release()后才会将lock最终unlocked。
所以可重入锁就是基于Lock增加了lock的owner机制,lock的owner是自身,可以继续acquire(),并将计数器加一。
threading module的Condition类(对象)
Condition Variable-条件变量,和Lock总是有着关联,底层机制应当还是使用Lock来实现的,Condition Variable的一个很好的应用场景就是“生产者-消费者”模型:
# Consume an itemwith cv: cv.wait_for(an_item_is_available) get_an_available_item()# Produce one itemwith cv: make_an_item_available() cv.notify()
condition机制如下图所示:
即Consumer等待条件满足,而Producer则触发条件满足,这样来做线程间的同步和通信。
threading module的Semaphore类(对象)
Semaphore内部维护一个计数器,每次acquire()计数器减一,每次release()计数器加一,计数器不能为负数。
threading module的Event类(对象)
线程通信最为简单的机制,一个线程抛出一个信号,另外线程等待这个信号。
threading module的Timer类(对象)
Timer用于某个动作需要等待一定时间后才开始执行。Timer是Thread的子类,除了start()方法,Timer还有cancel()方法来停止timer。
代码示例:
def hello(): print("hello, world")t = Timer(30.0, hello)t.start() # after 30 seconds, "hello, world" will be printed
threading module的Barrier类(对象)
Barrier类用于多个线程间互相等待的场景,每个线程通过调用wait()尝试传输barrier,并会block直到所有线程都传输了barrier。线程最终会同步release。
举例:
b = Barrier(2, timeout=5)def server(): start_server() b.wait() while True: connection = accept_connection() process_server_connection(connection)def client(): b.wait() while True: connection = make_connection() process_client_connection(connection)
Python多线程编程-queue模块
queue是同步的队列类,multi-producer, multi-consumer队列,主要用于threading编程中,多线程之间的安全通信。queue实现了所有需要的锁语义。且实现了3类queue:
queue module的类和异常
queue module的Queue类(对象)
另外还有两个方法,用于支持入队的任务是否被daemon消费者线程处理的跟踪:
Queue.task_done()和Queue.join()。
- [Language]Python的多线程
- [Language]Python的模块
- [Language]Python的面向对象
- python-language/tips/
- [Language]Python中的注释
- 《Natural Language Processing with Python》6.2节的一些错误
- [Dynamic Language] Python 取一年中某周的起始日期
- Python里的多线程
- python的多线程实例
- python的多线程分析
- python的多线程
- python的多线程示例
- Python多线程的学习
- python的多线程
- python的多线程基础设施
- 多线程的python实现
- python的多线程
- Python的多线程
- MATLAB蚁群算法TSP详细注释
- 第8周项目2-对称矩阵压缩存储的实现与应用(1)
- 第七周 【项目3
- mysql数据库
- JavaScript+DOM编程艺术(清晰中文版)笔记1
- [Language]Python的多线程
- C++ 内联函数
- DNN在TensorFlow框架的实现
- Java Gson 使用,Gson将字符串转为list
- Codeforces Round #441 C. Classroom Watch
- 数据安全-欢迎来稿
- 【知识整理】Node.js-Koa之Context、HTTP Response类型
- Scrapy安装报错:AttributeError: 'module' object has no attribute 'OP_NO_TLSv1_1'解决办法
- slf4j-api、slf4j-log4j12以及log4j之间的关系