python之线程学习
一、进程与线程简介
- 进程
进程是程序的一次执行,由进程段、数据段、进程控制块三部分组成。具体三个基本状态,就绪、执行、阻塞,是一个拥有资源的独立单位。
- 线程
属于进程的一个实体,拥有极少的资源。也具有三个基本状态,就绪、执行、拥塞。可以认为是一个情形进程。
- 关系
一个进程可以创建多个线程;一个进程创建的多个线程共享其资源;
进程开销较大,线程开销较小;进程撤销时间长,线程撤销时间短。
- 多进程/线程的运行
由主机的操作系统给每个进程/线程安排一个小时间片,在所有的进程/线程中快速切换,使每个执行单元都能得到CPU的执行时间。
多核系统上多进程分用不同的CPU核心。
- 注意点
python解释器内部使用了全局解释器锁(GIL),现在python进程只能在一个CPU核上运行。
二、进程的生命周期
三、python中threading模块
- Thread对象:用来创建线程
- Thread对象属性:
- start():启动线程
- run():启动线程的方法
- join():等待
- is_alive():返回该线程的活动状态
- name:线程名
- id:线程ID
- deamon:后台标志
- 获取当前线程
current_thread()
- 获取所有活动线程
enumerate()
四、线程的创建方法
1、直接实例化threading中Thread对象,并将线程的参数传入
实例化参数如下:
Thread(target = None,name = None,args = (),kwargs = {})
- target参数为要传入的函数名
- name参数为线程的名称
- args元组行参数
- import threading
- import time
- def calc():
- sum = 0
- for i in range(30):
- sum += i
- time.sleep(0.1)
- print(sum)
- if __name__ == '__main__':
- ths = [threading.Thread(target = calc) for i in range(2)]
- for th in ths:
- th.start()
运行结果:
- 435
- 435
2、通过继承Threading中的Thread对象,然后实例化并启动它。
注:新定义的Thread中如果定义了__init__(),需要先调用父类的__init__()
- import threading
- import time
- class MyThread(threading.Thread):
- def run(self):
- sum = 0
- for i in range(30):
- sum += i
- time.sleep(0.1)
- print(sum)
- if __name__ == '__main__':
- ths = [MyThread() for i in range(2)]
- for th in ths:
- th.start()
五、线程之间的关系
- 独立线程
- 等待线程
- 后台线程
- 线程同步1
共享资源只能被一个线程使用,先到先得。
- 线程同步2
操作有先后,典型的例子是生产者与消费者。线程A先操作,做一些初始化动作,线程B才能使用。
- 线程同步3
资源个数有上限
- 线程通信
六、线程各关系的实现
1、等待线程
join方法,被调用join方法的线程一直拥塞调用者的线程,直到自己结束。
也就是一个线程等待另一线程运行完才开始运行
- import threading,time
- class MyThread(threading.Thread):
- def run(self):
- for i in range(9):
- print('thread:',i)
- time.sleep(0.1)
- if __name__ == '__main__':
- m = MyThread()
- m.start()
- m.join()
- for i in range(5):
- print('main:',i)
- time.sleep(0.1)
运行结果:
- thread: 0
- thread: 1
- thread: 2
- thread: 3
- thread: 4
- thread: 5
- thread: 6
- thread: 7
- main: 0
- main: 1
- main: 2
- main: 3
- main: 4
2、后台线程
被设置为后台运行的线程,会在主程序退出时自杀
实现步骤:
- 建立线程
- 设置线程的deamon属性为True
- 启动线程
- import threading,time
- def backthread():
- print('backthread start...')
- time.sleep(3)
- print('backthread end...')
- def mainthread():
- print('mainthread start...')
- time.sleep(1)
- print('mainthread end...')
- th1 = threading.Thread(target = backthread)
- th1.deamon = True
- th2 = threading.Thread(target = mainthread)
- print('start...')
- th1.start()
- th2.start()
- print('end...')
运行结果:
- start...
- backthread start...
- mainthread start...
- end...
- mainthread end...
- backthread end...
2、线程同步
2.1 指令锁threading.Lock
- 加锁 acquire(blocking = True,timeout = -1)
- 释放锁 release()
- import threading,time,random
- share = 4
- class MyThread(threading.Thread):
- def __init__(self,i):
- super().__init__()
- self.i = i
- def run(self):
- global share
- for i in range(3):
- lock.acquire()
- print(share)
- share += self.i
- time.sleep(random.random())
- print('+',self.i,'=',share)
- lock.release()
- lock = threading.Lock()
- if __name__ == '__main__':
- m = MyThread(2)
- mm = MyThread(6)
- m.start()
- mm.start()
运行结果:
- 4
- + 2 = 6
- 6
- + 2 = 8
- 8
- + 6 = 14
- 14
- + 6 = 20
- 20
- + 6 = 26
- 26
- + 2 = 28
2.2 可重入锁 threading.RLock
与指令锁的区别,对于已经锁定的资源,在该线程内部还可以在锁一次。
支持的方法:
- acquire(block = Ture,timeout = -1)
- release()
锁定多少次,就要释放多少次!
2.3 条件变量threading.Condition
支持的方法:
- acquire()
- release()
- wait(timeout = None) 释放锁并进入等待拥塞,直到唤醒或者超时,这个线程才会继续运行。
- notify(n = 1) 如果一个线程处于wait状态,使用notify()进行唤醒
- notify_all 唤醒所有线程
使用范围:
实现严格次序操作的线程间通信
典型实例:
生产者/消费者(先生产,后消费)
线程之间可以相互通知,已达到默契的配合
- import threading,time
- share = 0
- share_cond = threading.Condition()
- class ProThread(threading.Thread):
- def __init__(self):
- super().__init__()
- self.name = 'produce'
- def run(self):
- global share
- if share_cond.acquire():
- while True:
- if not share:
- share += 1
- print(self.name,share)
- share_cond.notify()
- share_cond.wait()
- time.sleep(1)
- class CustomTread(threading.Thread):
- def __init__(self):
- super().__init__()
- self.name = 'produce'
- def run(self):
- global share
- if share_cond.acquire():
- while True:
- if share:
- share -= 1
- print(self.name,share)
- share_cond.notify()
- share_cond.wait()
- time.sleep(1)
- if __name__ == '__main__':
- p = ProThread()
- c = CustomTread()
- p.start()
- c.start()
运行结果:
- produce 1
- produce 0
- #一直循环下去...
2.4 信号量 threading.Semaphore()
实例化是指定使用量
支持的方法:
- acquire(blocking = Ture,timeout = None) 锁定资源
- release() 释放锁
使用其内置计数器,锁定时+1;释放时-1;计数器为0则拥塞
使用范围:
用于实现对稀缺资源的控制,比如需要控制稀缺资源的用户数
- import threading,time
- sema = threading.Semaphore(2)
- class SemaThread(threading.Thread):
- def __init__(self,name):
- super().__init__()
- self.name = name
- def run(self):
- if sema.acquire():
- print(self.name,' get resource.')
- time.sleep(1)
- print(self.name,' release resource.')
- sema.release()
- if __name__ == '__main__':
- res = [SemaThread(str(i) + 'sema') for i in range(5)]
- for i in res:
- i.start()
运行结果:
- 0sema get resource.
- 1sema get resource.
- 1sema release resource.
- 0sema release resource.
- 3sema get resource.
- 2sema get resource.
- 2sema release resource.
- 3sema release resource.
- 4sema get resource.
- 4sema release resource.
3、线程通信 threading.Event()
作用:
管理一个内部标志,实现一个线程,唤醒其他线程
支持的方法:
- set() 设置内部标志位False
- clear() 设置内部标志为False
- wait([timeout])拥塞线程,直到内部标志位True
- import threading,time
- eve = threading.Event()
- class MyThreadWait(threading.Thread):
- def run(self):
- self.name = 'Wait Thread'
- print(self.name,'waitting...')
- eve.wait()
- print(self.name,'Start...')
- eve.clear()
- class MyThreadMain(threading.Thread):
- def run(self):
- time.sleep(3)
- print('Main thread set event flag!')
- eve.set()
- if __name__ == '__main__':
- mm = MyThreadMain()
- mw = MyThreadWait()
- mm.start()
- mw.start()
运行结果:
- Wait Thread waitting...
- Main thread set event flag!
- Wait Thread Start...
4、定时执行threading.Timer
使用方法:
threading.Timer(3,start)
说明:
此进程3sec之后运行
python之线程学习的更多相关文章
- python自动化开发学习 进程, 线程, 协程
python自动化开发学习 进程, 线程, 协程 前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...
- Python之线程、进程和协程
python之线程.进程和协程 目录: 引言 一.线程 1.1 普通的多线程 1.2 自定义线程类 1.3 线程锁 1.3.1 未使用锁 1.3.2 普通锁Lock和RLock 1.3.3 信号量(S ...
- python threading基础学习
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' """ python是支持多线程的,并 ...
- python全栈学习--day1
计算机基础 CPU:中央处理器 内存:4GB,8GB,临时处理事务的地方,供给CPU数据. 硬盘:相当于电脑的数据库,存储着大量的数据,文件,电影等. 操作系统:执行者,支配所有关系 window ...
- 一文了解Python的线程
问题 什么是线程? 如何创建.执行线程? 如何使用线程池ThreadPoolExecutor? 如何避免资源竞争问题? 如何使用Python中线程模块threading提供的常用工具? 目录 1. 什 ...
- 《Python》线程池、携程
一.线程池(concurrent.futures模块) #1 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 P ...
- python源码学习(一)——python的总体架构
python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...
- 孤荷凌寒自学python第四十三天python 的线程同步之Queue对象
孤荷凌寒自学python第四十三天python的线程同步之Queue对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Queue对象是直接操作队列池的对象,队列中可以存放多种对象,当然也 ...
- 孤荷凌寒自学python第四十一天python的线程同步之Event对象
孤荷凌寒自学python第四十一天python的线程同步之Event对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 鉴于Lock锁与RLock锁均宣告没有完全完成同步文件操作的问题,于 ...
随机推荐
- [js高手之路]深入浅出webpack教程系列8-(postcss-loader,autoprefixer,html-loader,less-loader,ejs-loader)用法
我们接着上文,那么在上篇文章的最后,写到了css-loader的用法,如果你用心发现,就能看到我在style.css样式文件中写了一个这样的样式: div { transition: all ease ...
- [转]Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp84 Random即:java.util.Random, ThreadL ...
- 转:【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17225469 在Java中,可以通过配合调用Object对象的wait()方法和no ...
- Beta阶段事后诸葛亮分析
1.总结的提纲内容 a. 项目管理之事后诸葛亮会 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要解决用户无意识花钱,无法清楚看见钱去 ...
- Java单元测试之覆盖率统计eclemma
安装 有两种安装方法 下载安装(推荐) 地址: http://sourceforge.net/projects/eclemma/ 将解压后的features和plugins目录下的文件分别拷贝到Ecl ...
- 团队作业8——第二次项目冲刺(Beta阶段)--第七天
会议照片: 燃尽图: 项目进展: 所有项目都已完成 进行app测试即使用情况评估 团队贡献比: 队员 角色 团队贡献比 陈麟凤 PM 17% 张志杰 DEV 18% 黄海鸿 TEST 16% 康建灿 ...
- 201521123022 《Java程序设计》 第五周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过? ...
- 201521123003《Java程序设计》第4周学习总结
1. 本章学习总结 你对于本章知识的学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 参考资料: 百度脑图 XMind 1.2 使用常规方法总结其他上课内容. (1)了解了类型转换(cast) ...
- 201521123087 《Java程序设计》第3周学习总结
1.本周学习总结 2. 书面作业 代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; publ ...
- Java中的基本数据类型和基本数据类型之间的转换
在Java中有8中基本数据类型,分别为: 整型: byte.short.int.long 浮点型:float.double 布尔型:boolean 字符型:char. byte: 8位, 封装 ...