一、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之线程相关的其他方法的更多相关文章

  1. Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程

    一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. ​ threadin ...

  2. python之线程相关操作

    1.线程: 一个进程可以有多个线程,共享一个进程的资源: 2.进程线程的区别:  进程是资源分配的最小单位,线程是程序执行的最小单位 3.python中线程模块threading, 提供的类: Thr ...

  3. python之线程相关操作(补充)

    1 线程的其他方法 import threading import time from threading import Thread, current_thread def f1(n): time. ...

  4. python开发线程:线程&守护线程&全局解释器锁

    一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python ...

  5. python 多线程编程之threading模块(Thread类)创建线程的三种方法

    摘录 python核心编程 上节介绍的thread模块,是不支持守护线程的.当主线程退出的时候,所有的子线程都将终止,不管他们是否仍在工作. 本节开始,我们开始介绍python的另外多线程模块thre ...

  6. python执行线程方法

    转自: http://www.jb51.net/article/71908.htm 由于python线程没有提供abort方法,所以我们需要自己想办法解决此问题,面对这一问题,小编帮大家解决phtho ...

  7. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  8. PyQt(Python+Qt)学习随笔:QTreeWidget中标题相关属性访问方法headerItem、setHeaderLabels

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件窗口可以有一个标题头,其中包含部件中每个列的节(即标题).QTreeWidget的标题属性包 ...

  9. python 字符串、列表、字典相关内建方法

    """字符串相关内建方法""" # a = ["qwe", "name", "sex&qu ...

随机推荐

  1. 2015 Tencent 线上模拟测试题

    第一题  下面的程序的输出结果是: A. 134122 B. 123412 C. 14302012 D. 143212 #include <iostream> using namespac ...

  2. xargs - 地下管道

    xargs - 地下管道 xargs 促使我去思!考,管道 | 的具象含义是什么. $ cat sample.txt Things to do today: Low:Go grocery shoppi ...

  3. 如何在页面上输出html标签:符号实体

    用符号实体来表示特殊字符,比如 "<" 代表 "<",">" 代表 ">","& ...

  4. 【问题解决记录】Error: Cannot find module '@ionic/app-scripts'

    主要问题为: ionic serve 编译在浏览器中预览项目时,提示报错 Error: Cannot find module '@ionic/app-scripts'.这个问题的主要现象就是创建的项目 ...

  5. let、var、const声明的区别

    前言 看了方应杭老师的一篇解释let的文章,对JavaScript中的声明有了深刻的理解,这里也就有了总结一下JavaScript中各种声明之间区别的这篇文章. JavaScript中变量声明机制 首 ...

  6. 克隆一个centos虚拟机的环境配置

    克隆环境预处理设置 iptables -F  #清除规则 /etc/init.d/iptables save vim /etc/selinux/config selinux=disabled   # ...

  7. 图片浏览 h5

    @{ Layout = null; } <html> <head> <script type="text/javascript" src=" ...

  8. 【JSP 标签】格式化日期

    在使用JSP开发页面时,java.util.Date在JSP页面直接输出的格式不好看,需要进行格式化. <%@ page language="java" contentTyp ...

  9. 【Eclipse】更改部署位置

    在使用eclipse启动tomcat时,偶尔会遇到应用没被部署的现象,导致访问时出现404 问题原因:应用部署在了eclipse自带的webapps中. 我们通常不喜欢eclipse自带的tomcat ...

  10. Oracle教程之学习笔记

    Oracle教程之学习笔记... ----------------------------------- Oracle教程:---学习笔记: ============================= ...