day30线程(Threads)
day30线程(Threads)
1、开启线程
一、什么是线程:
1.进程是资源分配的最小单位,线程是CPU调度的最小单位。每一个进程中至少有一个线程。
2.主进程中的线程称为主线程,其他开启的线程称为子线程
二、为什么用线程:
进程有两个缺点:
1.进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
2.进程在执行的过程中如果遇到阻塞,例如等待输入,整个过程就会挂起。即使进程中有些工作不依赖于输入的数据,也将无法执行。
# 而这就是为什么还要用线程
代码:
from threading import Thread
def task():
print('子线程')
if __name__ == '__main__':
t = Thread(target=task)
t.start()
print('主线程')
2、GIL全局解释器锁
GIL全局解释器锁的特点:
1.python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。
2.虽然python解释器可以“运行”多个线程,但在任意时刻只有一个线程在解释器中执行。
3.由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
常识:
1.python代码在解释器中执行,绝大部分在用:cpython解释器,少部分用:pypy解释器
2.GIL锁在解释器中存在,他只能在cpython解释器中,pypy解释器中不存在
3.起一个垃圾回收线程,起一个正常执行的线程,垃圾回收还没有回收完毕,另一个线程可能会抢占资源
4.设置一把全局解释器锁(GIL锁),有了这把锁,就保证同一时刻,只能有一个线程执行,只要线程想执行,那么,就必须拿到这把GIL锁
5.如果是IO密集型:选择线程,因为io不会用到cpu内核,线程在进程里了
6.如果是计算密集型:选择进程 # 计算密集型用多进程,计算io密集型用多线程
3、进程和线程的区别
一、开启效率的较量
from multiprocessing import Process
from threading import Thread
import time
# 开启进程的时间
def task():
time.sleep(1)
print(123)
if __name__ == '__main__':
ctime = time.time()
p = Process(target=task)
p.start()
p.join()
print(time.time() - ctime)
# 输出结果:1.0815215110778809
# 开启线程的时间
def task():
time.sleep(1)
print(123)
if __name__ == '__main__':
ctime = time.time()
t = Thread(target=task)
t.start()
t.join()
print(time.time() - ctime)
# 输出结果:1.0080914497375488
# 结论:进程消耗比线程消耗大很多
二、多线程和多进程进行pid的比较
# 进行pid的较量
from multiprocessing import Process
from threading import Thread
import os
def task():
print('hello',os.getpid())
if __name__ == '__main__':
# 注:开启多个进程,每个进程都有不同的pid
p1 = Process(target=task)
p2 = Process(target=task)
p1.start()
p2.start()
print('主进程/主进程pid',os.getpid())
# 注:在主进程下开启多个线程,每个线程都跟主进程pid一样
t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
print('主进程/主进程pid',os.getpid())
# 结论:开启多进程,每个进程的pid都是不同的。在主程序下开启多线程,每个线程pid都和主程序pid一样。
4、Thread类的其他方法
一、Thread实例对象的方法:
1.is_alive():返回线程是否活动
2.getName();返回线程的名称
3.setName():设置线程名称
二、threading模块提供的一些方法:
1.threading.currentThread():返回当前的线程变量
2.threading.enumerate():返回一个包含正在运行的线程的list。
3.threading.activeCount():范慧慧正在运行的线程数量,与len(threading.enumerate())有相同的结果。
代码:
from threading import Thread
import time
def task():
time.sleep(1)
print(123)
if __name__ == '__main__':
t = Thread(target=task)
t.start()
print(t.is_alive()) # 返回线程是否活动
print(t.getName()) # 返回线程的名称
t.setName('mmm') # 设置线程的名称
print(t.getName())
5、守护线程
p.isDaemon和t.setDaemon(True)的特点:主进程(线程)结束,子进程(线程)也随之结束。也根本不会运行子进程(线程)的程序。# 注意守护进程一定要放在start()之前,不然不会运行
代码:
from threading import Thread
import time
import os
def task():
time.sleep(1)
print('my is %s'%(os.getpid()))
if __name__ == '__main__':
t =Thread(target=task)
t.setDaemon(True) # 跟进程不一样,进程的是p.isDaemon
t.start()
print('主线程')
print(t.is_alive())
# 返回结果:主线程,True,特点主线程结束,子线程也结束。
6、同步锁(互斥锁)
代码:
from threading import Thread,Lock
import time
def task(lock):
global n
lock.acquire() # 上锁
time.sleep(1)
n -= 1
lock.release() # 释放锁
if __name__ == '__main__':
n = 10
l = []
lock = Lock()
for i in range(10):
t = Thread(target=task,args=(lock, ))
t.start()
l.append(t)
for j in l:
j.join()
print(n) # 结果肯定为0,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全
# 补充:Lock在Process中为进程锁,在Thread中为互斥锁。
7、信息量(Semaphore)
# Semaphore:信息量可以理解为多把锁,同时允许多个进程量更改数据
代码:
from threading import Thread,Semaphore
import time
import random
sm = Semaphore(2) # 允许两个线程
def task(i):
sm.acquire()
print('线程:%s进来了'%i)
time.sleep(random.randint(1,3))
print('线程:%s出去了'% i)
sm.release()
if __name__ == '__main__':
for i in range(6):
t = Thread(target=task,args=(i, ))
t.start()
8、Enent事件
Enent事件的用法:
1.一些线程需要等到其他线程执行完成之后才能执行,类似于发射信号
2.比如一个线程等待另一个线程执行结束在继续执行
代码:
from threading import Thread, Event
import time
def girl(event):
print('女神正在谈恋爱中')
time.sleep(3)
event.set() # 发射信号
print('女神分手了')
def boy(i, event):
print('屌丝:%s正在等待女神分手' % i)
event.wait() # 正在等待
print('屌丝:%s开始展开追求' % i)
if __name__ == '__main__':
event = Event()
t = Thread(target=girl, args=(event,))
t.start()
for i in range(5):
t1 = Thread(target=boy, args=(i, event))
t1.start()
day30线程(Threads)的更多相关文章
- ARM官方《CMSIS-RTOS教程》之线程Threads
创建线程Creating Threads 一旦RTOS开始运行,就会有很多系统调用来管理和控制活跃的线程.默认情况下,main()函数自动被创建为第一个可运行的线程.在第一个例子里我们使用main() ...
- 笔记 线程(threads)
线程:CPU使用的基本单元(线程ID.程序计数器.寄存器集合.栈). 多线程:一个进程有多个线程 多线程的优点: 增加响应度:当一个交互程序部分阻塞,该程序能继续执行 一个应用程序在同一地址空间有多个 ...
- 在Linux下面如何查看tomcat已经使用多少线程(Threads)
先用 ps aux |grep tomcat 查看tomcat的 PID 再用 ps -T -p <PID>|wc -l 查看线程
- SYSBIOS学习笔记---线程(Threads)
在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...
- Android---53---多线程下载
采用HttpURLConnection HttpURLConnection从继承URLConnection,它也可以被用来发送到指定的网站GET求 POST求. 办法: int getResponse ...
- 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼
1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...
- Python并发编程之线程消息通信机制任务协调(四)
大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...
- Perl多线程(1):解释器线程的特性
线程简介 线程(thread)是轻量级进程,和进程一样,都能独立.并行运行,也由父线程创建,并由父线程所拥有,线程也有线程ID作为线程的唯一标识符,也需要等待线程执行完毕后收集它们的退出状态(比如使用 ...
- 【学习笔记】tensorflow队列和线程
目录 Tensorflow队列 同步执行队列 队列管理器 异步执行队列 线程协调器 在使用TensorFlow进行异步计算时,队列是一种强大的机制. 为了感受一下队列,让我们来看一个简单的例子.我们先 ...
随机推荐
- Vue面试题2
Class与Style绑定工作有用过吗: 有,后台管理系统菜单.主题色切换 .tab选项卡等..... 计算属性和侦听器区别.使用场景: 计算属性有缓存.并且是响应式依赖缓存,调用不加小括号 利用vu ...
- Jmeter 踩坑记录(七)
1.master连不上Slave机 解决方法:telnet 192.168.xx.xx 1099 看IP 端口通不通,如果通 OK,不通,检查关闭防火墙或者开放端口 2.salve 连不上 mast ...
- (十)JDBC(重点)
10.1 数据库驱动 驱动:声卡,显卡,数据库 我们的程序会通过 数据库 驱动和数据库打交道 10.2 JDBC SUN公司为了简化 开发人员的(对数据库的统一)操作,提供了一个(Java操作数据 ...
- HTTP1.1 Keep-Alive到底算不算长连接?
在基础架构部沉浸了半年,有一些认知刷新想和童靴们交代一下, 不一定全面,仅代表此时的认知, 也欢迎筒靴们提出看法. 本文聊一聊口嗨用语:"长连接.短连接", 文章会按照下面的思维导 ...
- 菜鸡的Java笔记 Object 类
Object 类 Object类 的主要作用 Object 类的常用方法 内容 虽然有了对象的向上转型,可以解决了参数的统一问题,但是 ...
- silky微服务框架的服务治理介绍
目录 服务治理的概念 服务注册与发现 负载均衡 超时 故障转移(失败重试) 熔断保护(断路器) 限流 RPC限流 HTTP限流 1. 添加配置 2. 注册服务 3.启用 AspNetCoreRateL ...
- 学不懂Netty?看不懂源码?不存在的,这篇文章手把手带你阅读Netty源码!
阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...
- Maven中所用的Dependency查找方法
用了Maven,所需的JAR包就不能再像往常一样,自己找到并下载下来,用IDE导进去就完事了,Maven用了一个项目依赖(Dependency)的概念,用俗话说,就是我的项目需要用你这个jar包,就称 ...
- 关于【【故障公告】数据库服务器 CPU 近 100% 引发的故障(源于 .NET Core 3.0 的一个 bug)】IS NOT NULL测试
测试如图,Core_Users的PhoneNumber可为空,存在索引,记录数1500000+ 增加is not null,查询计划消耗增加了一个0%的筛选器消耗,IO消耗如下一模一样 如果是IS N ...
- [hdu7022]Jsljgame
先考虑$x=y$的情况,此时即是一个平等博弈,因此考虑$sg$函数 具体的,有$sg(n)=\begin{cases}0&(n=0)\\mex(\{sg(n-i)\mid 1\le i\le ...