线程的有两种使用方法,一种是在函数使用,一种是放在类中使用。
1,在函数中使用多线程
语法如下:
|
thread.start_new_thread(function,args[,kwargs])
|
参数说明:
|
function-线程函数。
args-传递给线程函数的参数,必须是个tuple类型。
kwargs-可选参数。
|
下面是一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def run(num):
print'hi , i am a thread.',num
def main():
threads=[]
foriinrange(5):
t=threading.Thread(target=run,args=(i,))
threads.append(t)
t.start()
fortinthreads:
t.join()
if__name__=='__main__':
print'start -->'
main()
print'go here -->'
|
运行结果:
|
start-->
hi,iamathread.0
hi,iamathread.1
hi,iamathread.2
hi,iamathread.3
hi,iamathread.4
go here-->
|
2,在类中多使用线程
下面是在类中使用线程的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
classMyThread(threading.Thread):
def __init__(self,num):
self.num=num
super(MyThread,self).__init__()
def run(self):
print'i am a thread,',self.num
time.sleep(1)
def main():
threads=[]
foriinrange(5):
t=MyThread(i)
threads.append(t)
t.start()
fortinthreads:
t.join()
if__name__=='__main__':
print'start -->'
main()
print'go here-->
|
-
run(),需要重写,编写代码实现所需要的功能。
-
getName(),获得线程对象名称
-
setName(),设置线程对象名称
-
start(),启动线程
-
join([timeout]),等待另一线程结束后再运行。
-
setDaemon(bool),设置子线程是否随主线程一起结束,必须在
start()
之前调用,默认为False
。
-
isDaemon(),判断线程是否随主线程一起结束。
-
isAlive(),检查线程是否在运行中。
join
方法的作用是阻塞主进程(无法执行join
以后的语句),主线程等待这个线程结束后,才可以执行下一条指令。多线程多join
的情况下,依次执行各线程的join
方法,前头一个结束了才能执行后面一个。无参数,则等待到该线程结束,才开始执行下一个线程的join
。设置参数后,则等待该线程这么长时间就不管它了(而该线程并没有结束)。不管的意思就是可以执行后面的主进程了。
3,线程同步与互斥锁
线程之所以比进程轻量,其中一个原因就是他们共享内存。也就是各个线程可以平等的访问内存的数据,如果在短时间“同时并行”读取修改内存的数据,很可能造成数据不同步。例如下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var=0
classIncreThread(Thread):
def run(self):
globalvar
print'before,var is ',var
var+=1
print'after,var is ',var
def use_incre_thread():
threads=[]
foriinrange(50):
t=IncreThread()
threads.append(t)
t.start()
fortinthreads:
t.join()
print'After 10 times,var is ',var
if__name__=='__main__':
use_incre_thread()
|
有一个全局变量var
,五十个线程,每个线程对var
变量进行加 1 运算,但是当你多运行几次后,发现并不是每次的运行结果都是 50,为什么呢?
在var
是 10 的时候,线程t1
读取了var
,这个时刻cpu
将控制权给了另一个线程t2
。t2
线程读到的var
也是 10,t1
和t2
都把var
加到 11,当时我们期望的是t1 t2
两个线程使var
+ 2 变成 12。在这里就有了资源竞争,相同的情况也可能发生在其它的线程间,所以出现了最后的结果小于 50 的情况。
为了避免线程不同步造成数据不同步,可以对资源进行加锁。也就是访问资源的线程需要获得锁,才能访问。threading
模块提供了一个 Lock
功能,修改代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var=0
lock=Lock() #创建锁
classIncreThread(Thread):
def run(self):
globalvar
lock.acquire() #获取锁
print'before,var is ',var
var+=1
print'after,var is ',var
lock.release() #释放锁
def use_incre_thread():
threads=[]
foriinrange(50):
t=IncreThread()
threads.append(t)
t.start()
fortinthreads:
t.join()
print'After 10 times,var is ',var
if__name__=='__main__':
use_incre_thread()
|
虽然线程可以共享内存,但是一个线程不能影响其他线程内的变量(非全局变量)。
4,死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少发生,但一旦发生就会造成应用的停止响应。下面是一个死锁的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
mutex_a=Lock()
mutex_b=Lock()
classMyThread(Thread):
def task_b(self):
ifmutex_a.acquire():
print'thread get a mutex_a',self.name
time.sleep(1)
ifmutex_b.acquire():
print'get a mutex_b',self.name
mutex_b.release()
mutex_a.release()
def task_a(self):
ifmutex_b.acquire():
print'thread get a mutex_b',self.name
time.sleep(1)
ifmutex_a.acquire():
print'get a mutex_a',self.name
mutex_a.release()
mutex_b.release()
def run(self):
self.task_a()
self.task_b()
if__name__=='__main__':
threads=[MyThread()foriinrange(2)]
print threads
fortinthreads:
t.start()
|
线程需要执行两个任务,两个任务都需要获取锁,当两个任务得到锁后,就需要等另外锁释放。
5,可重入锁
为了支持在同一线程中多次请求同一资源,python
提供了可重入锁(RLock
)。RLock
内部维护着一个Lock
和一个counter
变量,counter
记录了acquire
的次数,从而使得资源可以被多次require
。直到一个线程所有的acquire
都被release
,其他的线程才能获得资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
mutex=threading.RLock()
classMyThread(threading.Thread):
def run(self):
ifmutex.acquire(1):
print'threading gte mutex:',self.name
time.sleep(1)
mutex.acquire()
mutex.release()
mutex.release()
def main():
print'start main threading:'
threads=[MyThread()foriinrange(2)]
fortinthreads:
t.start()
fortinthreads:
t.join()
print'end main threading.'
if__name__=='__main__':
main()
|
6,后台线程
使用多线程默认情况下,当主线程退出之后,即使子线程没有 join
,子线程也依然会继续执行。如果希望主线程退出后,其子线程也退出而不再执行,则需要设置子线程为后台线程。python
提供了setDaemon
方法,将子线程与主线程进行绑定,当主线程退出时子线程的生命也随之结束。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
classMyThread(threading.Thread):
def run(self):
wait_time=random.randrange(1,10)
print'thread %s will wait %s s'%(self.name,wait_time)
time.sleep(wait_time)
time.sleep(30)
print'thread %s finished.'%self.name
def main():
print'start thread:'
foriinrange(3):
t=MyThread()
t.setDaemon(1)
t.start()
print'end thread.'
if__name__=='__main__':
main()
|
运行结果:
|
start thread:
thread Thread-1will wait9s
thread Thread-2will wait1s
thread Thread-3will wait7s
endthread.
|
分享到:
相关推荐
本文详细介绍了PHP的基本语法、变量类型、运算符号以及文件上传和发邮件功能的实现方法,适合初学者了解和掌握PHP的基础知识。
公司金融整理的word文档
Prometheus Python客户端Prometheus的官方 Python 客户端。安装pip install prometheus-client这个包可以在PyPI上找到。文档文档可在https://prometheus.github.io/client_python上找到。链接发布发布页面显示项目的历史记录并充当变更日志。吡啶甲酸
DFC力控系统维护及使用
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
2019-2023GESP,CSP,NOIP真题.zip
博文链接 https://blog.csdn.net/weixin_47560078/article/details/127712877?spm=1001.2014.3001.5502
包含: 1、jasminum茉莉花 2、zotero-style 3、greenfrog 4、zotero-reference 5、translate-for-zotero 用法参考:https://zhuanlan.zhihu.com/p/674602898
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
python技巧学习.zip
2023 年“泰迪杯”数据分析技能赛 A 题 档案数字化加工流程数据分析 完整代码
echarts 折线图数据源文件
Visual Studio Code 的 Python 扩展Visual Studio Code 扩展对Python 语言提供了丰富的支持(针对所有积极支持的 Python 版本),为扩展提供了访问点,以无缝集成并提供对 IntelliSense(Pylance)、调试(Python 调试器)、格式化、linting、代码导航、重构、变量资源管理器、测试资源管理器等的支持!支持vscode.devPython 扩展在vscode.dev (包括github.dev )上运行时确实提供了一些支持。这包括编辑器中打开文件的部分 IntelliSense。已安装的扩展Python 扩展将默认自动安装以下扩展,以在 VS Code 中提供最佳的 Python 开发体验Pylance - 提供高性能 Python 语言支持Python 调试器- 使用 debugpy 提供无缝调试体验这些扩展是可选依赖项,这意味着如果无法安装,Python 扩展仍将保持完全功能。可以禁用或卸载这些扩展中的任何一个或全部,但会牺牲一些功能。通过市场安装的扩展受市场使用条款的约束。可
Centos6.x通过RPM包升级OpenSSH9.7最新版 升级有风险,前务必做好快照,以免升级后出现异常影响业务
5 总体设计.pptx
Python 版 RPAv1.50 • 使用案例• API 参考 • 关于 和制作人员 • 试用云 • PyCon 视频 • Telegram 聊天 • 中文 • हिन्दी • 西班牙语 • 法语 • বাংলা • Русский • 葡萄牙语 • 印尼语 • 德语 • 更多..要为 RPA(机器人流程自动化)安装此 Python 包 -pip install rpa要在 Jupyter 笔记本、Python 脚本或交互式 shell 中使用它 -import rpa as r有关操作系统和可选可视化自动化模式的说明 -️ Windows -如果视觉自动化有故障,请尝试将显示缩放级别设置为推荐的 % 或 100% macOS -由于安全性更加严格,请手动安装 PHP并查看PhantomJS和Java 弹出窗口的解决方案 Linux -视觉自动化模式需要在 Linux 上进行特殊设置,请参阅如何安装 OpenCV 和 Tesseract Raspberry Pi - 使用此设置指南在 Raspberry Pies(低成本自
原生js识别手机端或电脑端访问代码.zip
浏览器
内容概要:本文介绍了基于Spring Boot和Vue开发的旅游可视化系统的设计与实现。该系统集成了用户管理、景点信息、路线规划、酒店预订等功能,通过智能算法根据用户偏好推荐景点和路线,提供旅游攻略和管理员后台,支持B/S架构,使用Java语言和MySQL数据库,提高了系统的扩展性和维护性。 适合人群:具有一定编程基础的技术人员,特别是熟悉Spring Boot和Vue框架的研发人员。 使用场景及目标:适用于旅游行业,为企业提供一个高效的旅游推荐平台,帮助用户快速找到合适的旅游信息和推荐路线,提升用户旅游体验。系统的智能化设计能够满足用户多样化的需求,提高旅游企业的客户满意度和市场竞争力。 其他说明:系统采用现代化的前后端分离架构,具备良好的可扩展性和维护性,适合在旅游行业中推广应用。开发过程中需要注意系统的安全性、稳定性和用户体验。