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)的更多相关文章

  1. ARM官方《CMSIS-RTOS教程》之线程Threads

    创建线程Creating Threads 一旦RTOS开始运行,就会有很多系统调用来管理和控制活跃的线程.默认情况下,main()函数自动被创建为第一个可运行的线程.在第一个例子里我们使用main() ...

  2. 笔记 线程(threads)

    线程:CPU使用的基本单元(线程ID.程序计数器.寄存器集合.栈). 多线程:一个进程有多个线程 多线程的优点: 增加响应度:当一个交互程序部分阻塞,该程序能继续执行 一个应用程序在同一地址空间有多个 ...

  3. 在Linux下面如何查看tomcat已经使用多少线程(Threads)

    先用 ps aux |grep tomcat 查看tomcat的 PID 再用 ps -T -p <PID>|wc -l 查看线程

  4. SYSBIOS学习笔记---线程(Threads)

    在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...

  5. Android---53---多线程下载

    采用HttpURLConnection HttpURLConnection从继承URLConnection,它也可以被用来发送到指定的网站GET求 POST求. 办法: int getResponse ...

  6. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  7. Python并发编程之线程消息通信机制任务协调(四)

    大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...

  8. Perl多线程(1):解释器线程的特性

    线程简介 线程(thread)是轻量级进程,和进程一样,都能独立.并行运行,也由父线程创建,并由父线程所拥有,线程也有线程ID作为线程的唯一标识符,也需要等待线程执行完毕后收集它们的退出状态(比如使用 ...

  9. 【学习笔记】tensorflow队列和线程

    目录 Tensorflow队列 同步执行队列 队列管理器 异步执行队列 线程协调器 在使用TensorFlow进行异步计算时,队列是一种强大的机制. 为了感受一下队列,让我们来看一个简单的例子.我们先 ...

随机推荐

  1. Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)

    在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...

  2. best-time-to-buy-and-sell-stock leetcode C++

    Say you have an array for which the i th element is the price of a given stock on day i. If you were ...

  3. JMH 使用指南

    简介 JMH(Java Microbenchmark Harness)是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级.该工具是由 Oracle 内部实现 JIT 的大 ...

  4. Cobar SQL审计的设计与实现

    背景介绍 Cobar简介 Cobar 是阿里开源的一款数据库中间件产品. 在业务高速增长的情况下,数据库往往成为整个业务系统的瓶颈,数据库中间件的出现就是为了解决数据库瓶颈而产生的一种中间层产品. 在 ...

  5. seq2seq之双向解码

    目录 背景介绍 双向解码 基本思路 数学描述 模型实现 训练方案 双向束搜索 代码参考 思考分析 文章小结 在文章<玩转Keras之seq2seq自动生成标题>中我们已经基本探讨过seq2 ...

  6. uni-app路径规划(打开第三方地图实现)

    百度网盘链接:https://pan.baidu.com/s/1-Ys13GFcnKXB1wkJotcwMw 提取码:16gp 把js文件放在common目录下 引入:    import pathP ...

  7. 关于 better-scroll 设置了以后无法滚动或不生效的问题

    首先在mounted里面注册组件  例:let scroll = new BScroll("#commondityLeftList")   然后打印实例化对象,例:console. ...

  8. Python Nose 自动化测试框架介绍

    文章目录 1. unittest 简介 1.1 python 单元测试 1.2 unittest 测试框架 1.3 默认模式 1.4 手工模式 2. nose 扩展框架 2.1 `nose` 的安装和 ...

  9. Redis这15个“雷坑”,别问我咋知道的……

    来源:https://dbaplus.cn/news-158-3836-1.html

  10. url,href,src 之间的区别

    url 统一资源定位符 <style> #bg{ background-image:url("img/bg.png"); } </style> 区别: sr ...