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. Python matplotlib 概率论与数理统计 伯努利分布 二项分布

    Python 代码实现 二项分布 import numpy as np import matplotlib.pyplot as plt import math from scipy import st ...

  2. 第01课 OpenGL窗口(2)

    下一段包括了所有的绘图代码.任何您所想在屏幕上显示的东东都将在此段代码中出现.以后的每个教程中我都会在例程的此处增加新的代码.如果您对OpenGL已经有所了解的话,您可以在 glLoadIdentit ...

  3. sqlldr导入报错:field in data file exceeds maximum length

    检查报错日志提示:field in data file exceeds maximum length REMARK字段设置:varchar2(2000),报错的内容也没有超1000个字符 表中定义的字 ...

  4. 【数据结构&算法】04-线性表

    目录 前言 线性表的定义 线性表的数据类型&操作 线性表操作 数据类型定义 复杂操作 线性表的顺序存储结构 顺序存储结构的定义 顺序存储方式 数据长度和线性表长度的区别 地址的计算方法 顺序存 ...

  5. Celery Received unregistered task of type

    celery -A proj worker --loglevel=info 这个错误原因在于proj这里没有包含对应的task, 可以在这里导入需要的task即可

  6. airflow redis sentinel

    获取master name subscribe __sentinel__:hello mysql plugin table not found mysqld --initialize-insecure ...

  7. 3组-Alpha冲刺-3/6

    一.基本情况 队名:发际线和我作队 组长博客:链接 小组人数:10 二.冲刺概况汇报 黄新成(组长) 过去两天完成了哪些任务 文字描述 使用labelimg工具对采集的数据进行标注,安装alphapo ...

  8. java meil

    import java.util.Date; import java.util.List; import java.util.Properties; import javax.activation.D ...

  9. 菜鸡的Java笔记 类图

    类图        1.如何实现类图的描述        2.时序图的使用                    从实际i的开发标准:应该在项目编写钱设计类图        而现在的开发大部分情况下, ...

  10. [atAGC054D]ox

    对于两个字符串$s$和$t$(保证其中每一种字符个数相同),定义$s$和$t$的相对逆序对数为$s$得到$t$的最少交换次数,显然同种字符相对顺序保持不变,因此即依次编号后的逆序对数 问题不妨看作构造 ...