一、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. 程序员/PM怎么让项目预估的时间更加准确

    项目时间的估算对项目的成败至关重要.项目时间管理包括了项目按时完成所需的各个过程.但是,在实际项目中,经常出现项目延期,估算严重不准确的现象. 一个我曾经共事过的很有经验的项目经理曾宣称说,他会拿程序 ...

  2. eval & exec(绕过长度限制思路学习)

    eval & exec知识点记录--原文章phithon,只是记录一下我自己的学习过程. 1.eval & exec if(strlen($param)<17 && ...

  3. View.post() 不靠谱的地方你知道吗?

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章. 未经允许,不得转载. 一.前言 有时候,我们会需要 ...

  4. 【Linux】用yum安装JDK(转)

    1.查看yum库中都有哪些jdk版本(暂时只发现了openjdk) [root@localhost ~]# yum search java|grep jdk ldapjdk-javadoc.x86_6 ...

  5. 【渗透课程】第一篇-Web渗透需要接触的语言

    ---恢复内容开始--- 上一篇我们讲过了,Web渗透的基本原理,在原理中我们也提到了Web应用程序(脚本语言),本章就谈到了Web渗透要涉及的语言. 涉及语言: 1.html:是前段语言的其中一个, ...

  6. The C++ Programming Language 学习笔记 第5章 指针、数组和结构

    1.关于输出指向字符的指针的值. 现在定义,char c='a',char* pc=&c.在C中,输出该值只需要printf("%p\n",pc);而在C++中,如果cou ...

  7. Junit4的最简单例子

    首先是JUnit的百度百科介绍: 接下来是JUnit4的最简单例子,使用的开发软件为Eclispe(里面集成了JUnit): 1.建立一个java project: 2.建立一个java class: ...

  8. 报表 jasper + ireport5.6

    下载 iReport-5.6.0,jdk7,以及众多lib , 这里我提供下资源(我的百度云) 安装好iReport-5.6.0和jdk7,  在安装目录的\etc\ireport.conf,修改其中 ...

  9. [2012-06-29]sed根据行号范围执行替换

    测试数据: personball@vostro:SHELL$cat aaa <instrumentation android:name="aaa" android:name= ...

  10. wcf 上传文件报413,404和发布错误

    上传文件错误: 其实要修改所有的服务,不管是服务端还是客户端,Binding那边增加一个没有设置名字的默认配置就OK了:  <binding   closeTimeout="00:10 ...