一、join方法

(1)开一个主线程

  1. from threading import Thread,currentThread
  2. import time
  3. def walk():
  4. print('%s is running'%currentThread().getName())
  5. time.sleep(2)
  6. print('%s is done'%currentThread().getName())
  7. if __name__ == '__main__':
  8. # for i in range(10):
  9. p=Thread(target=walk)
  10. p.start()
  11. p.join()
  12. print('主') #主线程在等p.join执行

开一个主线程

(2)开多个主线程,并发运行

  1. from threading import Thread,currentThread
  2. import time
  3. def walk():
  4. print('%s is running'%currentThread().getName())
  5. time.sleep(2)
  6. print('%s is done'%currentThread().getName())
  7. if __name__ == '__main__':
  8. l=[]
  9. for i in range(10):
  10. p=Thread(target=walk)
  11. l.append(p)
  12. p.start()
  13. # p.join() #在p.start() 跟p.join()就会变为串行,一个一个的运行
  14. for p in l:
  15. p.join()
  16. print('主')

开多个主线程

(3)并发运行 互斥锁之锁局部的 ,用所只锁住你对共享数据修改的部分

加锁:

  1. from threading import Thread,currentThread,Lock
  2. import time
  3. n=100
  4. def walk():
  5. # 并发运行
  6. time.sleep(2)
  7. global n
  8. mutex.acquire()
  9. # 串行
  10. temp=n
  11. time.sleep(0.01)
  12. n=temp-1 #数据可能同是减1,可能数据会乱
  13. mutex.release()
  14. if __name__ == '__main__':
  15. mutex=Lock()
  16. l=[]
  17. start = time.time()
  18. for i in range(100):
  19. p=Thread(target=walk)
  20. l.append(p)
  21. p.start()
  22. for p in l:
  23. p.join()
  24. stop = time.time()
  25. print('n:%s run_time : %s' %(n,stop - start))

不加锁:

  1. from threading import Thread,currentThread,Lock
  2. import time
  3. n=100
  4. def walk():
  5. time.sleep(2)
  6. global n
  7. # mutex.acquire()
  8. temp=n
  9. time.sleep(0.1)
  10. n=temp-1 #数据可能同是减1,可能数据会乱
  11. # mutex.release()
  12. if __name__ == '__main__':
  13. mutex=Lock()
  14. start = time.time()
  15. for i in range(10):
  16. p=Thread(target=walk)
  17. p.start()
  18. p.join()
  19. stop = time.time()
  20. print('n:%s run_time : %s' %(n,stop - start)) #至少21秒

并发运行,不加锁

  1. 主线程运行完毕是在所有线程所在的进程内所有非守护线程运行完毕才运行

二、GIL本质是一把互斥锁,将并发转成串行,以此来控制同一时间内共享数据只能被一个任务修改,

     进而保证数据的安全

  1. from threading import Thread,currentThread,Lock
  2. import time
  3. n=100
  4. def work():
  5. time.sleep(2)
  6. global n
  7. time.sleep(0.5)
  8. mutex.acquire()
  9. temp=n
  10. time.sleep(0.1)
  11. n=temp-1
  12. mutex.release()
  13. if __name__ == '__main__':
  14. mutex=Lock()
  15. t1=Thread(target=work)
  16. t2=Thread(target=work)
  17. t3=Thread(target=work)
  18. t1.start()
  19. t2.start()
  20. t3.start()

三、多线程性能测试

  1. 1'''
    多进程
    优点:可以利用多核
    缺点:开销大
  2.  
  3. 多线程
    优点:开销小
    缺点:不可以利用多核
    '''
  1. from multiprocessing import Process
  2. from threading import Thread
  3. import time
  4. def work():
  5. res=0
  6. for i in range(10000000):
  7. res+=i
  8.  
  9. if __name__ == '__main__':
  10. l=[]
  11. start=time.time()
  12. for i in range(4):
  13. # p=Process(target=work) #0.9260530471801758
  14. p=Thread(target=work) #0.9260530471801758
  15. l.append(p)
  16. p.start()
  17.  
  18. for p in l:
  19. p.join()
  20.  
  21. stop=time.time()
  22. print('%s' %(stop-start))

计算机密集型--开启多进程

  1. from multiprocessing import Process
  2. from threading import Thread
  3. import time
  4. def work():
  5. time.sleep(2)
  6.  
  7. if __name__ == '__main__':
  8. l=[]
  9. start=time.time()
  10. for i in range(400):
  11. p=Process(target=work)
  12. # p=Thread(target=work)
  13. l.append(p)
  14. p.start()
  15.  
  16. for p in l:
  17. p.join()
  18.  
  19. stop=time.time()
  20. print('%s' %(stop-start))

I/O密集型---开启多线程

(2)应用:

             多线程用于IO密集型,如socket,爬虫,web
            多进程用于计算密集型,如金融分析

四、死锁与递归锁

死锁:

  1. from threading import Thread,RLock
  2. import time
  3. mutexA=RLock()
  4. class MyThread(Thread):
  5. def run(self):
  6. self.f1()
  7. self.f2()
  8. def f1(self):
  9. mutexA.acquire()
  10. print('%s 拿到A锁'%self.name)
  11. mutexA.acquire()
  12. print('%s 拿到B锁' % self.name)
  13. mutexA.release()
  14. mutexA.release()
  15. def f2(self):
  16. mutexA.acquire()
  17. print('%s 拿到A锁' % self.name)
  18. time.sleep(1)
  19. mutexA.acquire()
  20. print('%s 拿到B锁' % self.name)
  21. mutexA.release()
  22. mutexA.release()
  23. if __name__ == '__main__':
  24. for i in range(10):
  25. t=MyThread()
  26. t.start()

解决死锁的方法

递归锁:用RLock代替Lock

  1. from threading import Lock,Thread,RLock
  2. import time
  3. # mutexA=Lock()
  4. # mutexB=Lock()
  5. mutexB=mutexA=RLock()
  6. class MyThread(Thread):
  7. def run(self):
  8. self.f1()
  9. self.f2()
  10. def f1(self):
  11. mutexA.acquire()
  12. print('\033[32m%s 拿到A锁' %self.name)
  13. mutexB.acquire()
  14. print('\033[45m%s 拿到B锁' %self.name)
  15. mutexB.release()
  16. mutexA.release()
  17. def f2(self):
  18. mutexB.acquire()
  19. print('\033[32m%s 拿到B锁' %self.name)
  20. time.sleep(1)
  21. mutexA.acquire()
  22. print('\033[45m%s 拿到A锁' %self.name)
  23. mutexA.release()
  24. mutexB.release()
  25. if __name__ == '__main__':
  26. for i in range(10):
  27. t=MyThread()
  28. t.start()

递归锁

五、信号量

信号量和进程一样

信号量就是一把锁,可以有多把钥匙

  1. from threading import Thread,Semaphore,currentThread
  2. import time,random
  3. sm=Semaphore(5)
  4. def task():
  5. sm.acquire()
  6. print('%s 上厕所' %currentThread().getName())
  7. time.sleep(random.randint(1,3))
  8. print('%s 走了' %currentThread().getName())
  9. sm.release()
  10. if __name__ == '__main__':
  11. for i in range(20):
  12. t=Thread(target=task)
  13. t.start()

六、事件

Event

  1. vent.isSet():返回event的状态值;
  2. event.wait():如果 event.isSet()==False将阻塞线程;
  3. event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
  4. event.clear():恢复event的状态值为False
  1. from threading import Thread,currentThread,Event
  2. import time
  3. e=Event()
  4. def traffic_ligths():
  5. time.sleep(1)
  6. e.set()
  7. def car():
  8.  
  9. print('\033[45m%s等'%currentThread().getName())
  10. e.wait()
  11. print('\033[43m%s开'%currentThread().getName())
  12. if __name__ == '__main__':
  13. print('绿灯')
  14. for i in range(10):
  15. p=Thread(target=car)
  16. p.start()
  17. # print('绿灯')
  18. time.sleep(5)
  19. print('红灯')
  20. traffic_ligth=Thread(target=traffic_ligths)
  21. traffic_ligth.start()

红绿灯事列

  1.  
  1. from threading import Thread, currentThread, Event
  2. import time
  3. e = Event()
  4. def conn_mysql():
  5. count = 1
  6. while not e.is_set():
  7. if count > 3:
  8. raise ConnectionError('尝试链接的次数太多了')
  9. print('\033[45m%s 第%s次尝试' % (currentThread().getName(), count))
  10. e.wait(timeout=1)
  11. count += 1
  12. print('\033[45m%s 开始链接' %currentThread().getName())
  13. def check_myql():
  14. print('\033[45m%s 开始检测 my_sql....' %currentThread().getName())
  15. time.sleep(2)
  16. e.set()
  17. if __name__ == '__main__':
  18. for i in range(2):
  19. p = Thread(target=conn_mysql)
  20. p.start()
  21. p = Thread(target=check_myql)
  22. p.start()

链接——sql

七、定时器

定时器,是n秒后执行操作

  1. rom threading import Timer
  2.  
  3. def hello(n):
  4. print("hello, world",n)
  5.  
  6. t = Timer(3, hello,args=(123,))
  7. t.start() # after 1 seconds, "hello, world" will be printed

定时器

八、线程queue

queue队列,用法与进程queue一样

q=queue.queue()  先进先出

  1. q=queue.Queue(3) #先进先出
  2. q.put('first')
  3. q.put('second')
  4. q.put('third')
  5. # q.put('fourth')
  6.  
  7. print(q.get())
  8. print(q.get())
  9. print(q.get())

q=queue.LifoQueue()   先进后出

  1. q=queue.LifoQueue() #先进后出
  2. q.put('first')
  3. q.put('second')
  4. q.put('third')
  5. # q.put('fourth')
  6.  
  7. print(q.get())
  8. print(q.get())
  9. print(q.get())
  1. put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
  1. import queue
  2. q=queue.PriorityQueue()
  3. q.put((20,'a'))
  4. q.put((10,'b'))
  5. q.put((30,'c'))
  6. print(q.get())
  7. print(q.get())
  8. 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. JavaWeb(二)jsp运行原理,九大内置对象

    JSP运行原理: 每个JSP页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ...

  2. DLL基础

    Visual C++在创建DLL导出函数时,可能会对原始的函数名做修改.例如: int WINAPI Add(int nLeft, int nRight) 导出后的函数名称是_Add@8. 下面两种方 ...

  3. 在学习泛型时遇到的困惑经常与func<T,U>混淆

    在学习泛型时遇到的困惑经常与func<T,U>混淆,总认为最后一个值是返回类型.现在区分一下,原来问题出在泛型委托上. C#委托的介绍(delegate.Action.Func.predi ...

  4. jvm系列 (三) ---锁的优化

    锁的优化 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 我的博客目录 锁的四种状态 从低到高,只能升级不能降级 无锁状态 偏向锁 ...

  5. OpenCms创建网站过程图解——献给OpenCms的初学者们

    很多人都听说了OpenCms,知道了它的强大,索性的下载安装了,终于见到了久违OpenCms,看到了它简洁的界面,欣喜过后却不免一脸茫然,这个东西怎么用,我怎么用它来建站,从哪开始,无从下手,找资料, ...

  6. 图片浏览 h5

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

  7. SQL查询--选择运算(1)

    /**  本贴使用MySQL数据库  **/ WHERE子句可以实现关系代数中的选择运算,用于查询满足选择条件的元组,常用的查询条件有: 1.比较运算:>,>=,<,<=,=, ...

  8. emacs命令记录

    C-代表按住Ctrl键 M-代表按住Alt键,也可以用按一下ESC放开代替   最先要记住的 M-x <cmd>      输入指令执行,在输入时用Tab可以自动补全或列出项目 C-g   ...

  9. poj2912 Rochambeau

    Description N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is th ...

  10. fatal error LNK1201:写入程序数据库“***.pdb”时出错;请检查是否是磁盘空间不足、路径无效或权限不够

    问题很简单,是因为你的程序正在运行,或者windbg工具在执行dump文件,文件被占用,所以无法写入: