多任务-线程基础与总结
2018-07-22 05:57:19来源:博客园 阅读 ()
一、对线程的理解
1.一个程序运行起来至少有一个进程,一个进程至少有一个线程
2.处理器cpu分配给线程,即cpu真正运行的是线程中的代码
3.分配cpu给线程时,是通过时间片轮训方式进行的
4.进程是操作系统分配程序执行资源的单位,而线程是进程的一个实体,是CPU调度和分配的单位。
二、python实现多线程的两种方式
1、创建函数并且传入Thread 对象中
示例如下:
# 引入threading线程模块 import threading import time def download_music(): """模拟下载歌曲,需要5秒钟下载完成""" for i in range(5): time.sleep(1) # 休眠1秒 print("---正在下载歌曲%d---" % i) def play_music(): """模拟播放歌曲,需要5秒钟下载完成""" for i in range(5): time.sleep(1) # 休眠1秒 print("---正在播放歌曲%d---" % i) def main(): # 创建线程对象t1 # target: 指向新开启的线程要执行的代码 t1 = threading.Thread(target=download_music) t2 = threading.Thread(target=play_music) t1.start() # 启动线程,既然线程开始执行 t2.start() if __name__ == '__main__': main()
2.继承Thread类,创建一个新的class,将要执行的代码 写到run函数里面
# 自定义类,继承threading.Thread class MyThread(threading.Thread): def run(self): for i in range(5): time.sleep(1) # name属性中保存的是当前线程的名字 msg = "I'm " + self.name + ' @ ' + str(i) print(msg) if __name__ == '__main__': # 通过MyThread创建线程对象 t1 = MyThread() # 开始执行线程 t1.start()
三、线程何时开启,何时结束
1.子线程何时开启,何时运行
当调用thread.start()时 开启线程,再运行线程的代码
2.子线程何时结束
子线程把target指向的函数中的语句执行完毕后,或者线程中的run函数代码执行完毕后,立即结束当前子线程
3.查看当前线程数量
通过threading.enumerate()可枚举当前运行的所有线程
4.主线程何时结束
所有子线程执行完毕后,主线程才结束
四、多线程(共享全局变量的问题)
1.在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
2.缺点就是,多线程对全局变量随意遂改可能造成全局变量的混乱(即线程非安全)
3.如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确,即会遇到线程安全问题
五、互斥锁
1.当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
2.线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。
3.互斥锁为资源引入一个状态:锁定/非锁定
4.某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
5.hreading模块中定义了Lock类,可以方便的处理锁定:
# 创建锁 mutex = threading.Lock() # 锁定 mutex.acquire() # 释放 mutex.release()
6.例如:使用互斥锁完成2个线程对同一个全局变量各加100万次的操作
import threading import time g_num = 0 def test1(num): global g_num for i in range(num): mutex.acquire() # 上锁 g_num += 1 mutex.release() # 解锁 print("---test1---g_num=%d"%g_num) def test2(num): global g_num for i in range(num): mutex.acquire() # 上锁 g_num += 1 mutex.release() # 解锁 print("---test2---g_num=%d"%g_num) # 创建一个互斥锁 # 默认是未上锁的状态 mutex = threading.Lock() # 创建2个线程,让他们各自对g_num加1000000次 p1 = threading.Thread(target=test1, args=(1000000,)) p1.start() p2 = threading.Thread(target=test2, args=(1000000,)) p2.start() # 等待计算完成 while len(threading.enumerate()) != 1: time.sleep(1) print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
加了互斥锁就不会出现资源竞争而导致结果与理想不合。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- Python连载30-多线程之进程&线程&线程使用 2019-08-13
- python_0基础开始_day07 2019-08-13
- 【Python】语法基础 | 开始使用Python 2019-08-13
- Python基础总结之初步认识---class类的继承(终)。第十六天 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