python之线程相关操作
2019-01-15 07:05:06来源:博客园 阅读 ()
1.线程: 一个进程可以有多个线程,共享一个进程的资源;
2.进程线程的区别:
进程是资源分配的最小单位,线程是程序执行的最小单位
3.python中线程模块threading, 提供的类: Thread, Lock, Rlock, Semaphore, Event, 等等
4.线程的创建方式
# 第一种 # from threading import Thread # def f1(s): # print('我是%s' % s) # def f2(s): # print('我是%s' % s) # # if __name__ == '__main__': # t = Thread(target=f1, args=(1,)) # t1 = Thread(target=f1, args=(2,)) # t.start() # t1.start() # print('我是主线程') # 第二种 from threading import Thread class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): print('%s今天还是不能皮' % self.name) if __name__ == '__main__': t = MyThread('Jerry') t.start() print('主线程')
6.查看线程的进程id(同进程查看方式一样)
import os from threading import Thread def f1(n): print('1号', os.getpid()) print('%s号线程任务' % n) def f2(n): print('2号', os.getpid()) print('%s号线程任务' % n) if __name__ == '__main__': t1 = Thread(target=f1, args=(1,)) t2 = Thread(target=f2, args=(2,)) t1.start() t2.start() print('主线程', os.getpid()) print('主线程')
7. 在进程之间数据是空间隔离的, 而在线程中是数据共享的
import time from threading import Thread # 通过对全局变量的修改来验证线程之间是数据共享的, 共享同一进程中的数据 num = 100 def f1(): time.sleep(3) global num num = 3 print('子线程的num', num) if __name__ == '__main__': t = Thread(target=f1) t.start() t.join() # 等待子线程运行结束才继续向下执行 print('主线程的num', num)
8.多进程和多线程的效率对比
对于io密集型的, 多线程的时间较快
def f1(): time.sleep(1) #io密集型 if __name__ == '__main__': # 查看一下20个线程执行20个任务的执行时间 t_s_time = time.time() t_list = [] for i in range(5): t = Thread(target=f1,) t.start() t_list.append(t) [tt.join() for tt in t_list] t_e_time = time.time() t_dif_time = t_e_time - t_s_time # 查看一下20个进程执行同样的任务的执行时间 p_s_time = time.time() p_list = [] for i in range(5): p = Process(target=f1,) p.start() p_list.append(p) [pp.join() for pp in p_list] p_e_time = time.time() p_dif_time = p_e_time - p_s_time print('多线程的执行时间:', t_dif_time) print('多jincheng的执行时间:', p_dif_time)
计算型:
import time from threading import Thread from multiprocessing import Process def f1(): # 计算型: n = 10 for i in range(10000000): n = n + i if __name__ == '__main__': # 查看一下20个线程执行20个任务的执行时间 t_s_time = time.time() t_list = [] for i in range(5): t = Thread(target=f1,) t.start() t_list.append(t) [tt.join() for tt in t_list] t_e_time = time.time() t_dif_time = t_e_time - t_s_time # 查看一下20个进程执行同样的任务的执行时间 p_s_time = time.time() p_list = [] for i in range(5): p = Process(target=f1,) p.start() p_list.append(p) [pp.join() for pp in p_list] p_e_time = time.time() p_dif_time = p_e_time - p_s_time print('多线程的执行时间:', t_dif_time) print('多jincheng的执行时间:', p_dif_time)
9.锁,同步,互斥锁 为了保护多线成中数据的完整性和线程间状态的同步.(同进程的锁一样)
在线程锁中, 会产生死锁现象. 同时抢锁
import time from threading import Thread, Lock, RLock def f1(locA, locB): # print('xxxx') # time.sleep(0.1) locA.acquire() print('f1>>1号抢到了A锁') time.sleep(1) locB.acquire() print('f1>>1号抢到了B锁') locB.release() locA.release() def f2(locA, locB): print('22222') time.sleep(0.1) locB.acquire() print('f2>>2号抢到了B锁') locA.acquire() time.sleep(1) print('f2>>2号抢到了A锁') locA.release() locB.release() if __name__ == '__main__': locA = Lock() locB = Lock() t1 = Thread(target=f1, args=(locA, locB)) t2 = Thread(target=f2, args=(locA, locB)) t1.start() t2.start()
递归锁解决了 死锁现象
import time from threading import Thread, Lock, RLock def f1(locA, locB): print('xxxxx') time.sleep(0.1) locA.acquire() print('f1>>>1号抢到了A锁') time.sleep(1) locB.acquire() print('f1>>>2号抢到了B锁') locB.release() locA.release() def f2(locA, locB): print('22222') time.sleep(0.1) locB.acquire() print('f2>>>1号抢到了A锁') time.sleep(1) locA.acquire() print('f2>>>2号抢到了B锁') locA.release() locB.release() if __name__ == '__main__': locA = locB = RLock() t1 = Thread(target=f1, args=(locA, locB)) t2 = Thread(target=f2, args=(locB, locA)) t1.start() t2.start()
10.多线程的程序不结束 和 多进程的程序不结束的区别
守护进程:主进程代码执行运行结束,守护进程随之结束
守护线程:守护线程会等待所有非守护线程运行结束才结束
import time from threading import Thread from multiprocessing import Process # 守护进程:主进程代码执行运行结束,守护进程随之结束 # 守护线程:守护线程会等待所有非守护线程运行结束才结束 def f1(): time.sleep(2) print('一号线程') def f2(): time.sleep(3) print('二号线程') def f3(): time.sleep(2) print('一号进程') def f4(): time.sleep(3) print('二号进程') if __name__ == '__main__': # t1 = Thread(target=f1,) # t2 = Thread(target=f2,) # # t1.daemon = True # 等非守护线程结束,守护线程才会结束 结果: 主线程结束 一号线程 二号线程 # t2.daemon = True # 结果: 主线程结束 一号线程 # t1.start() # t2.start() # print('主线程结束') p1 = Process(target=f3,) p2 = Process(target=f4,) # p1.daemon = True # 结果: 主进程 二号线程 p2.daemon= True # 结果: 主进程 一号线程 p1.start() p2.start() print('主进程')
11. GIL锁 : cpython解释器上的一把互斥锁, Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核
Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
原文链接:https://www.cnblogs.com/q455674496/p/10260446.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Python 常用系统模块整理
下一篇:聊聊技术写作的个人体会
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash