python之线程相关的其他方法
一、join方法
(1)开一个主线程
- from threading import Thread,currentThread
- import time
- def walk():
- print('%s is running'%currentThread().getName())
- time.sleep(2)
- print('%s is done'%currentThread().getName())
- if __name__ == '__main__':
- # for i in range(10):
- p=Thread(target=walk)
- p.start()
- p.join()
- print('主') #主线程在等p.join执行
开一个主线程
(2)开多个主线程,并发运行
- from threading import Thread,currentThread
- import time
- def walk():
- print('%s is running'%currentThread().getName())
- time.sleep(2)
- print('%s is done'%currentThread().getName())
- if __name__ == '__main__':
- l=[]
- for i in range(10):
- p=Thread(target=walk)
- l.append(p)
- p.start()
- # p.join() #在p.start() 跟p.join()就会变为串行,一个一个的运行
- for p in l:
- p.join()
- print('主')
开多个主线程
(3)并发运行 互斥锁之锁局部的 ,用所只锁住你对共享数据修改的部分
加锁:
- from threading import Thread,currentThread,Lock
- import time
- n=100
- def walk():
- # 并发运行
- time.sleep(2)
- global n
- mutex.acquire()
- # 串行
- temp=n
- time.sleep(0.01)
- n=temp-1 #数据可能同是减1,可能数据会乱
- mutex.release()
- if __name__ == '__main__':
- mutex=Lock()
- l=[]
- start = time.time()
- for i in range(100):
- p=Thread(target=walk)
- l.append(p)
- p.start()
- for p in l:
- p.join()
- stop = time.time()
- print('n:%s run_time : %s' %(n,stop - start))
不加锁:
- from threading import Thread,currentThread,Lock
- import time
- n=100
- def walk():
- time.sleep(2)
- global n
- # mutex.acquire()
- temp=n
- time.sleep(0.1)
- n=temp-1 #数据可能同是减1,可能数据会乱
- # mutex.release()
- if __name__ == '__main__':
- mutex=Lock()
- start = time.time()
- for i in range(10):
- p=Thread(target=walk)
- p.start()
- p.join()
- stop = time.time()
- print('n:%s run_time : %s' %(n,stop - start)) #至少21秒
并发运行,不加锁
- 主线程运行完毕是在所有线程所在的进程内所有非守护线程运行完毕才运行
二、GIL本质是一把互斥锁,将并发转成串行,以此来控制同一时间内共享数据只能被一个任务修改,
进而保证数据的安全
- from threading import Thread,currentThread,Lock
- import time
- n=100
- def work():
- time.sleep(2)
- global n
- time.sleep(0.5)
- mutex.acquire()
- temp=n
- time.sleep(0.1)
- n=temp-1
- mutex.release()
- if __name__ == '__main__':
- mutex=Lock()
- t1=Thread(target=work)
- t2=Thread(target=work)
- t3=Thread(target=work)
- t1.start()
- t2.start()
- t3.start()
三、多线程性能测试
- (1)'''
多进程
优点:可以利用多核
缺点:开销大- 多线程
优点:开销小
缺点:不可以利用多核
'''
- from multiprocessing import Process
- from threading import Thread
- import time
- def work():
- res=0
- for i in range(10000000):
- res+=i
- if __name__ == '__main__':
- l=[]
- start=time.time()
- for i in range(4):
- # p=Process(target=work) #0.9260530471801758
- p=Thread(target=work) #0.9260530471801758
- l.append(p)
- p.start()
- for p in l:
- p.join()
- stop=time.time()
- print('%s' %(stop-start))
计算机密集型--开启多进程
- from multiprocessing import Process
- from threading import Thread
- import time
- def work():
- time.sleep(2)
- if __name__ == '__main__':
- l=[]
- start=time.time()
- for i in range(400):
- p=Process(target=work)
- # p=Thread(target=work)
- l.append(p)
- p.start()
- for p in l:
- p.join()
- stop=time.time()
- print('%s' %(stop-start))
I/O密集型---开启多线程
(2)应用:
多线程用于IO密集型,如socket,爬虫,web
多进程用于计算密集型,如金融分析
四、死锁与递归锁
死锁:
- from threading import Thread,RLock
- import time
- mutexA=RLock()
- class MyThread(Thread):
- def run(self):
- self.f1()
- self.f2()
- def f1(self):
- mutexA.acquire()
- print('%s 拿到A锁'%self.name)
- mutexA.acquire()
- print('%s 拿到B锁' % self.name)
- mutexA.release()
- mutexA.release()
- def f2(self):
- mutexA.acquire()
- print('%s 拿到A锁' % self.name)
- time.sleep(1)
- mutexA.acquire()
- print('%s 拿到B锁' % self.name)
- mutexA.release()
- mutexA.release()
- if __name__ == '__main__':
- for i in range(10):
- t=MyThread()
- t.start()
解决死锁的方法
递归锁:用RLock代替Lock
- from threading import Lock,Thread,RLock
- import time
- # mutexA=Lock()
- # mutexB=Lock()
- mutexB=mutexA=RLock()
- class MyThread(Thread):
- def run(self):
- self.f1()
- self.f2()
- def f1(self):
- mutexA.acquire()
- print('\033[32m%s 拿到A锁' %self.name)
- mutexB.acquire()
- print('\033[45m%s 拿到B锁' %self.name)
- mutexB.release()
- mutexA.release()
- def f2(self):
- mutexB.acquire()
- print('\033[32m%s 拿到B锁' %self.name)
- time.sleep(1)
- mutexA.acquire()
- print('\033[45m%s 拿到A锁' %self.name)
- mutexA.release()
- mutexB.release()
- if __name__ == '__main__':
- for i in range(10):
- t=MyThread()
- t.start()
递归锁
五、信号量
信号量和进程一样
信号量就是一把锁,可以有多把钥匙
- from threading import Thread,Semaphore,currentThread
- import time,random
- sm=Semaphore(5)
- def task():
- sm.acquire()
- print('%s 上厕所' %currentThread().getName())
- time.sleep(random.randint(1,3))
- print('%s 走了' %currentThread().getName())
- sm.release()
- if __name__ == '__main__':
- for i in range(20):
- t=Thread(target=task)
- t.start()
六、事件
Event
- vent.isSet():返回event的状态值;
- event.wait():如果 event.isSet()==False将阻塞线程;
- event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
- event.clear():恢复event的状态值为False。
- from threading import Thread,currentThread,Event
- import time
- e=Event()
- def traffic_ligths():
- time.sleep(1)
- e.set()
- def car():
- print('\033[45m%s等'%currentThread().getName())
- e.wait()
- print('\033[43m%s开'%currentThread().getName())
- if __name__ == '__main__':
- print('绿灯')
- for i in range(10):
- p=Thread(target=car)
- p.start()
- # print('绿灯')
- time.sleep(5)
- print('红灯')
- traffic_ligth=Thread(target=traffic_ligths)
- traffic_ligth.start()
红绿灯事列
- from threading import Thread, currentThread, Event
- import time
- e = Event()
- def conn_mysql():
- count = 1
- while not e.is_set():
- if count > 3:
- raise ConnectionError('尝试链接的次数太多了')
- print('\033[45m%s 第%s次尝试' % (currentThread().getName(), count))
- e.wait(timeout=1)
- count += 1
- print('\033[45m%s 开始链接' %currentThread().getName())
- def check_myql():
- print('\033[45m%s 开始检测 my_sql....' %currentThread().getName())
- time.sleep(2)
- e.set()
- if __name__ == '__main__':
- for i in range(2):
- p = Thread(target=conn_mysql)
- p.start()
- p = Thread(target=check_myql)
- p.start()
链接——sql
七、定时器
定时器,是n秒后执行操作
- rom threading import Timer
- def hello(n):
- print("hello, world",n)
- t = Timer(3, hello,args=(123,))
- t.start() # after 1 seconds, "hello, world" will be printed
定时器
八、线程queue
queue队列,用法与进程queue一样
q=queue.queue() 先进先出
- q=queue.Queue(3) #先进先出
- q.put('first')
- q.put('second')
- q.put('third')
- # q.put('fourth')
- print(q.get())
- print(q.get())
- print(q.get())
q=queue.LifoQueue() 先进后出
- q=queue.LifoQueue() #先进后出
- q.put('first')
- q.put('second')
- q.put('third')
- # q.put('fourth')
- print(q.get())
- print(q.get())
- print(q.get())
- put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
- import queue
- q=queue.PriorityQueue()
- q.put((20,'a'))
- q.put((10,'b'))
- q.put((30,'c'))
- print(q.get())
- print(q.get())
- print(q.get())
python之线程相关的其他方法的更多相关文章
- Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程
一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. threadin ...
- python之线程相关操作
1.线程: 一个进程可以有多个线程,共享一个进程的资源: 2.进程线程的区别: 进程是资源分配的最小单位,线程是程序执行的最小单位 3.python中线程模块threading, 提供的类: Thr ...
- python之线程相关操作(补充)
1 线程的其他方法 import threading import time from threading import Thread, current_thread def f1(n): time. ...
- python开发线程:线程&守护线程&全局解释器锁
一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python ...
- python 多线程编程之threading模块(Thread类)创建线程的三种方法
摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...
- python执行线程方法
转自: http://www.jb51.net/article/71908.htm 由于python线程没有提供abort方法,所以我们需要自己想办法解决此问题,面对这一问题,小编帮大家解决phtho ...
- Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量
Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程: 1.线程是一堆指令,是操作系统调度 ...
- PyQt(Python+Qt)学习随笔:QTreeWidget中标题相关属性访问方法headerItem、setHeaderLabels
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件窗口可以有一个标题头,其中包含部件中每个列的节(即标题).QTreeWidget的标题属性包 ...
- python 字符串、列表、字典相关内建方法
"""字符串相关内建方法""" # a = ["qwe", "name", "sex&qu ...
随机推荐
- 【前端】向blog或网站中添加语法高亮显示代码方法总结
向blog或网站中添加语法高亮显示的代码方法总结 文章目录 预备知识 目标 第一类方法:嵌入 第二类方法:外部引用 第三类方法:忽略HTML和PHP 最近在写代码时遇到一个问题,就是如何让代码像在ID ...
- 错误Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:
今天写PHP代码,遇到了这个非常不友好的报错(Deprecated: mysql_connect(): The mysql extension is deprecated and will be re ...
- 【Linux】windows-linux、linux-linux文件互传
一.Linux下文件互传,scp命令实例 1.Linux下目录复制:本机->远程服务器 scp -r /home/abc/test1(本机目录路径) root@192.168.0.1:/hom ...
- HttpResponseMessage获取请求响应体内容
问题描述 使用httpClient获取的HttpResponseMessage类型的response,直接对其toString()获取的是请求的响应头,并没有获取响应体的内容 解决办法 HttpRes ...
- 转每天一个linux命令(7):mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- ReactNative环境搭建扩展篇——安装后报错解决方案
之前一篇写了<逻辑性最强的React Native环境搭建与调试>说了RN的安装,今天在这里做一个复盘,让我们能够更直观更深入的了解React Native(以下简称RN),这一篇重点来说 ...
- iOS,点击button拨打电话
//按钮点击拨打电话 -(void)kfclick:(UIButton *)btn { [[UIApplication sharedApplication] openURL:[NSURL URLWit ...
- [WPF]如何调试Data Binding
前言 在WPF开发中,将ViewModel中对象绑定到UI上时,会出现明明已经将数据对象Binding到UI,但是UI上就是不显示等等的问题.这篇博客将介绍WPF Data Binding相关的内容, ...
- Spring Aop 应用实例与设计浅析
0.代码概述 代码说明:第一章中的代码为了突出模块化拆分的必要性,所以db采用了真实操作.下面代码中dao层使用了打印日志模拟插入db的方法,方便所有人运行demo. 1.项目代码地址:https:/ ...
- SQL Server 2014 64位版本链接32位Oracle数据库
问题背景: 刚进入公司不久的BI新手,最近接部门的一个交接项目,需要在SQL Server上通过openquery来获取Oracle数据库的数据.各种配置,各种设置折腾了一周之久.在此,将自己的问题解 ...