多线程

在介绍Python中的线程之前,先明确一个问题,Python中的多线程是假的多线程!
为什么这么说,我们先明确一个概念,全局解释器锁(GIL)

什么是GIL

Python代码的执行由Python虚拟机(解释器)来控制,同时只有一个线程在执行。对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同时只有一个线程在运行。

为什么要GIL

为了线程间数据的一致性和状态同步的完整性

GIL的影响

只有一个线程在运行,无法使用多核。
在多线程环境中,Python虚拟机按照以下方式执行。1.设置GIL。2.切换到一个线程去执行。3.运行。4.把线程设置为睡眠状态。5.解锁GIL。6.再次重复以上步骤。比方我有一个4核的CPU,那么这样一来,在单位时间内每个核只能跑一个线程,然后时间片轮转切换。
但是Python不一样,它不管你有几个核,单位时间多个核只能跑一个线程,然后时间片轮转。
执行一段时间后让出,多线程在Python中只能交替执性,10核也只能用到1个核# 使用线程
from threading import Thread
def loop():while True:print("Copy?")if __name__ == '__main__':for i in range(3):t = Thread(target=loop)t.start()while True:pass# 而如果我们变成进程呢?cpu --100%
from multiprocessing import Process
def loop():while True:print("Copy?")if __name__ == '__main__':for i in range(3):t = Process(target=loop)t.start()while True:pass

多线程怎么使用多核

1、重写python编译器(官方cpython)如使用:PyPy解释器
2、调用C语言的链接库

cpu密集型(计算密集型)、I/O密集型

计算密集型任务由于主要消耗CPU资源,代码运行效率至关重要,C语言编写IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成,99%的时间花费在IO上,脚本语言是首选,C语言最差。

创建多线程

def doSth(arg):# 拿到当前线程的名称和线程号idthreadName = threading.current_thread().getName()tid = threading.current_thread().identfor i in ra rttid=%d" % (arg, i, threadName, tid))time.sleep(2)

1、使用_thread.start_new_thread开辟子线程

def simpleThread():# 创建子线程,执行doSth# 用这种方式创建的线程为【守护线程】(主线程死去“护卫”也随“主公”而去)_thread.start_new_thread(doSth, ("拍森",))mainThreadName = threading.current_thread().getName()print(threading.current_thread())# 5秒的时间以内,能看到主线程和子线程在并发打印for i in range(5):print("劳资是主线程@%s" % (mainThreadName))time.sleep(1)# 阻塞主线程,以使【守护线程】能够执行完毕while True:pass

2、 通过创建threading.Thread对象实现子线程

def threadingThread():# 默认不是【守护线程】t = threading.Thread(target=doSth, args=("大王派我来巡山",)) # args=(,) 必须是元组# t.setDaemon(True)  # 设置为守护线程t.start()  # 启动线程,调用run()方法

3、通过继承threading.Thread类,进而创建对象实现子线程

class MyThread(threading.Thread):def __init__(self, name, task, subtask):super().__init__()self.name = name  # 覆盖了父类的nameself.task = task  # MyThread自己的属性self.subtask = subtask  # MyThread自己的属性# 覆写父类的run方法,# run方法以内为【要跑在子线程内的业务逻辑】(thread.start()会触发的业务逻辑)def run(self):for i in range(5):print("【%s】并【%s】 *%d @%s" % (self.task, self.subtask, i, threading.current_thread().getName()))time.sleep(2)def classThread():mt = MyThread("小分队I", "巡山", "扫黄")mt.start()  #  启动线程

4、几个重要的API

def importantAPI():print(threading.currentThread())  # 返回当前的线程变量# 创建五条子线程t1 = threading.Thread(target=doSth, args=("巡山",))t2 = threading.Thread(target=doSth, args=("巡水",))t3 = threading.Thread(target=doSth, args=("巡鸟",))t1.start()  # 开启线程t2.start()t3.start()print(t1.isAlive())  # 返回线程是否活动的print(t2.isDaemon())  # 是否是守护线程print(t3.getName())  # 返回线程名t3.setName("巡鸟")  # 设置线程名print(t3.getName())print(t3.ident)  # 返回线程号# 返回一个包含正在运行的线程的listtlist = threading.enumerate()print("当前活动线程:", tlist)# 返回正在运行的线程数量(在数值上等于len(tlist))count = threading.active_count()print("当前活动线程有%d条" % (count))

线程冲突

'''
【线程冲突】示例:多个线程并发访问同一个变量而互相干扰
'''
import threading
import time
money = 0# CPU分配的时间片不足以完成一百万次加法运算,
# 因此结果还没有被保存到内存中就被其它线程所打断
def addMoney():global moneyfor i in range(1000000):money += 1print(money)# 创建线程锁
lock = threading.Lock()def addMoneyWithLock():# print("addMoneyWithLock")time.sleep(1)global money# print(lock.acquire())# if lock.acquire():#     for i in range(1000000):#         money += 1# lock.release()# 独占线程锁with lock:  # 阻塞直到拿到线程锁# -----下面的代码只有拿到lock对象才能执行-----for i in range(1000000):money += 1# 释放线程锁,以使其它线程能够拿到并执行逻辑# ----------------锁已被释放-----------------print(money)# 5条线程同时访问money变量,导致结果不正确
def conflictDemo():for i in range(5):t = threading.Thread(target=addMoney)t.start()# 通过线程同步(依次执行)解决线程冲突
def handleConflictBySync():for i in range(5):t = threading.Thread(target=addMoney)t.start()t.join()  # 一直阻塞到t运行完毕# 通过依次独占线程锁解决线程冲突
def handleConflictByLock():# 并发5条线程for i in range(5):t = threading.Thread(target=addMoneyWithLock)t.start()if __name__ == '__main__':# conflictDemo()# handleConflictBySync()handleConflictByLock()pass

死锁

死锁:是指一个资源被多次调用,而多次调用方都未能释放该资源就会造成一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。互相锁住对方线程需要的资源,造成死锁局面

线程安全

互斥锁
互斥锁状态:锁定/非锁定# 创建锁lock = threading.Lock()# 锁定lock.acquire()# 释放lock.release()
递归锁
递归锁,重用锁,用于解决死锁的问题,可重复锁# 递归锁
rlock = threading.RLOCK()

信号量Semaphore调度线程:控制最大并发量

'''
使用Semaphore调度线程:控制最大并发量
'''
import threading
import time# 允许最大并发量3
sem = threading.Semaphore(3)def doSth(arg):with sem:tname = threading.current_thread().getName()print("%s正在执行【%s】" % (tname, arg))time.sleep(1)print("-----%s执行完毕!-----\n" % (tname))time.sleep(0.1)if __name__ == '__main__':# 开启10条线程for i in range(10):threading.Thread(target=doSth, args=("巡山",), name="小分队%d" % (i)).start()

Python线程 一相关推荐

  1. python3 线程池源码解析_5分钟看懂系列:Python 线程池原理及实现

    概述 传统多线程方案会使用"即时创建, 即时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器 ...

  2. 什么是Python线程?Python线程如何创建?

    相信正在学习Python技术或者对Python语言有一定了解的人对于Python线程应该都不陌生,但是也有刚接触Python的小伙伴对于Python线程并不了解,今天小编就跟大家聊聊什么是Python ...

  3. python 线程锁 共享全局变量 线程通信

    python 线程锁 共享全局变量 线程通信 注意:全局变量不必做为参数传到函数里!!! import threading # 银行存钱和取钱 # 存钱1万次 def add():global mon ...

  4. python线程池阻塞队列_福利又来啦!python多线程进阶篇

    使用Python中的线程模块,能够同时运行程序的不同部分,并简化设计.如果你已经入门Python,并且想用线程来提升程序运行速度的话,希望这篇教程会对你有所帮助. 通过阅读本文,你将了解到:什么是死锁 ...

  5. python - 线程

    python之路--线程 简介 操作系统线程理论 线程概念的引入背景 线程的特点 进程和线程的关系 使用线程的实际场景 用户级线程和内核级线程(了解) 线程和python 理论知识 线程的创建Thre ...

  6. Python线程同步机制: Locks, RLocks, Semaphores, Condition

    为什么80%的码农都做不了架构师?>>>    翻译自Laurent Luce的博客 原文名称:Python threads synchronization: Locks, RLoc ...

  7. php 线程锁,如何使用python线程锁(实例解析)

    在这篇文章之中我们来了解一下什么是python线程锁.了解一下python线程锁的相关知识,以及线程锁在python编程之中能起到什么样的作用. 线程锁(互斥锁Mutex) 一个进程下可以启动多个线程 ...

  8. Python线程、进程知识整理

    一.python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 im ...

  9. python线程暂停_关于多线程:如何使“停止”按钮终止已经在Tkinter中运行的“开始”功能(Python)...

    我正在使用带有两个主要按钮的Tkinter制作GUI:"开始"和"停止". 您能否为以下代码提供建议,以使"停止"按钮终止由"开始 ...

  10. Python 线程和进程和协程总结

    Python 线程和进程和协程总结 线程和进程和协程 进程 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间.内存等)的基本单位: 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其 ...

最新文章

  1. TCP 传输控制协议(转)
  2. Magento教程 7:客制化网站
  3. 查询HTML标签select中options的值并定位其位置
  4. python多进程运行MIC(最大信息系数)
  5. [UE4]控制台命令,生成机器人
  6. MemCache在tomcat中的负载均衡和session交叉存放
  7. TCP/UDP协议简要梳理
  8. 一步一步安装 Windows Server 2008 Beta3(Code Name Longhorn)
  9. 【JavaSE基础】09-网络编程
  10. matlab绘制xy色度图函数
  11. 深入理解Binder机制1-AIDL原理
  12. ## Asset Store(unity商店) 如何下载已购买的资源?*
  13. 理论物理极础附录:有心力和行星轨道
  14. 计算机与网络技术 英语,计算机与网络英语词汇(S3)
  15. 虚幻开发工具包发布版本的版本信息
  16. golang interface 与 反射
  17. python 将中文数字转换为阿拉伯数字
  18. 搞金融不能用mysql_金融行业数据库何去何从
  19. SwiftUI 小专栏20200817汇总
  20. Ping32最新版支持钉邮监控

热门文章

  1. 黑盒测试技术中的等价类划分法、边界值分析法、因果图法和决策表法进行测试用例设计
  2. 汽车功能安全—HARA
  3. PotPlayer播放列表另存为
  4. java获取真实ip的方法
  5. 《人工智能本科专业知识体系与课程设置》笔记
  6. 大数据处理——Java
  7. Jacoco-报告改造实践
  8. 单向可控硅和双向可控硅的详细介绍(含引脚的分辨)
  9. python+OpenCV笔记(二十四):Shi-Tomasi角点检测
  10. 无需插件修改chrome浏览器UA标识为手机版