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 ...
随机推荐
- go环境的安装~
Golang环境搭建 Golang github地址:https://github.com/golang/go Golang的环境下载:https://golang.org/dl/ 安装过程就是nex ...
- 第2天:HTML常用标签
今天学完主要对所学知识点进行了整理. 一.超链接ahref:www.baidu.com(跳转页面):id名(锚点跳到相应div位置):01.rar(压缩包) target:_blank(新窗口打开): ...
- spring boot 登录注册 demo (二) -- 数据库访问
通过data-jpa来访问数据库 <dependency> <groupId>org.springframework.boot</groupId> <arti ...
- yii2 无法显示debug条的问题解决方法
显示debug条需要设置三个地方 一.web/index.php defined('YII_ENV') or define('YII_ENV', 'dev');//设置为开发者模式 二.config/ ...
- [js高手之路]设计模式系列课程-单例模式实现模态框
什么是单例呢? 单,就是一个的意思.例:就是实例化出来的对象,那合在一起就是保证一个构造函数只能new出一个实例,为什么要学习单例模式呢?或者说单例模式有哪些常见的应用场景.它的使用还是很广泛,比如: ...
- linux(一)之linux简介
其实在前几天我使用的是csdn来写博客,尝试了一下,发现真的太浪费时间了.可能是自己不太习惯的原因吧.所以最后还是换回使用博客园.接下来给大家带来的是linux,大家听到这里linux感觉很神秘的样子 ...
- NOIP[2015] Day2题解
问题 A: 跳石头 时间限制: 1 Sec 内存限制: 128 MB 题目描述 一年一度的"跳石头"比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石. ...
- ASP.NET 给Web中的网页添加Loading进度条形式
前段时间客户提了一个需求,要求给网站中某些功能添加进度条形式,因为某些功能查询的数据量太大,经常会出现点击Search按钮,但是没有任何反应的情况,会让用户以为网站挂掉了,导致投诉的事情发生,所以客户 ...
- 关于makefile中变量的多次赋值以及override指令
1 基本原则如下 1.1 原则1 变量的普通赋值是有先后顺序的,后面的赋值会覆盖掉前面的赋值. 1.2 原则2 使用的时候,用的是其前面最后的赋值,就算其后面有使用了override指令的赋值也不会影 ...
- css中使用变量
2017年3月,微软宣布 Edge 浏览器将支持 CSS 变量.这个重要的 CSS 新功能,所有主要浏览器已经都支持了. 声明css变量的时候,变量名前面要加两根连词线(--).变量名大小写敏感,-- ...