当前位置: 首页 > news >正文

【线程相关知识】

今日内容概要

  • 开启线程的两种方式
  • TCP服务端实现并发效果
  • 线程对象的join方法
  • 线程间数据共享
  • 线程对象属性及其他方法
  • 守护线程
  • 线程互斥锁
  • GIL全局解释器锁
  • 多进程与多线程的实际应用场景

今日内容详细


开启线程的两种方式
# import time
# from multiprocessing import Process
# from threading import Thread
#
#
# def task(name):
#     print('%s is running' % name)
#     time.sleep(1)
#     print('%s is over' % name)
#
#
# # 开启线程不需要在main下面执行代码 直接书写可以
# # 但是我们还是习惯性的将启动命令写在下面
# t = Thread(target=task, args=('egon',))
# t.start() # 创建线程的开销非常小,几乎是代码一执行线程就已经创建了
# print('主')from threading import Thread
import timeclass MyThread(Thread):def __init__(self,name):# 重写了别人的方法 又不知道别人的方法里有啥,你就调用父类的方法super().__init__()self.name = namedef run(self):print("%s is running" % self.name)time.sleep(1)print('egon dsb')if __name__ == '__main__':t = MyThread('egon')t.start()print('主')

TCP服务端实现平发的效果

import socket
from threading import Thread
from multiprocessing import Process"""
服务端1.要有固定的IP和PORT2.24小时不间断提供服务3.能够支持并发
"""
server = socket.socket()  # 括号内不加参数默认就是TCP
server.bind(('127.0.0.1', 8080))
server.listen(5)# 将服务的代码单独封装成一个函数
def task(conn):# 通信循环while True:try:data = conn.recv(1024)# 针对mac linux 客户端链接后if len(data) == 0: breakprint(data.decode('utf-8'))conn.send(data.upper())except ConnectionError as e:print(e)breakconn.close()# 链接循环
while True:conn, addr = server.accept()  # 接客# 叫其他人来服务客户t = Thread(target=task,args=(conn,))# t = Process(target=task,args=(conn,))t.start()"""客服端"""
import socketclient = socket.socket()
client.connect(('127.0.0.1', 8080))while True:client.send('hello word'.encode('utf-8'))data = client.recv(1024)print(data.decode('utf-8'))

线程对象的join方法

from threading import Thread
import timedef task(name):print('%s is running' % name)time.sleep(3)print('%s over' % name)if __name__ == '__main__':t = Thread(target=task,args=('egon', ))t.start()t.join() # 主线程等待子线程结束print('主')

同一个进程下的多个线程数据是共享的

from threading import Thread
import timemoney = 100def task():global moneymoney = 666print(money)if __name__ == '__main__':t = Thread(target=task)t.start()t.join()print(money) # 666

线程对象属性及其他方法

from threading import Thread, active_count, current_thread
import os, timedef task(n):# print('hello world', os.getpid())print('hello world', current_thread().name)time.sleep(n)if __name__ == '__main__':t = Thread(target=task, args=(1,))t1 = Thread(target=task, args=(2,))t.start()t1.start()t1.join()print('主',active_count()) # 统计当前正在活跃的线程数# print('主',current_thread().name)# print('主',os.getpid())

守护线程

# from threading import Thread
# import time
#
#
# def task(name):
#     print('%s is running' % name)
#     time.sleep(1)
#     print('%s over' % name)
#
#
# if __name__ == '__main__':
#     t = Thread(target=task, args=('egon',))
#     t.daemon = True
#     t.start()
#     print('主')"""
主线程结束后不会立刻结束 需要等待其他子线程结束才会结束因为主线程结束意味着所在的进程的结束
"""from threading import Thread
import timedef foo():print(123)time.sleep(1)print('end123')def func():print(456)time.sleep(3)print('end456')if __name__ == '__main__':t1 = Thread(target=foo)t2 = Thread(target=func)t1.daemon = Truet1.start()t2.start()print('主')

线程的互斥锁

from threading import Thread, Lock
import timemoney = 100
mutex = Lock()def task():global moneymutex.acquire()tmp = moneytime.sleep(0.1)money = tmp - 1mutex.release()if __name__ == '__main__':t_list = []for i in range(100):t = Thread(target=task)t.start()t_list.append(t)for t in t_list:t.join()print(money)

GIL全局解释器锁

"""
cpython
Jpython
pypypython
但是普遍使用的都是cpython因为cpython中的内存管理不是线程安全的
内存管理(垃圾回收机制)1.应用计数2.标记清楚3.分代回收"""
"""
重点:1.GIL不是python的特点而是cpython解释器的特点2.GIL是保证解释器级别的数据安全3.GIL会导致同一个进程下的多个线程的无法同时执行4.针对不同的数据还是需要加不同的锁处理5.解释性语言的通病:同一个进程下多线程无法执行
"""

GIL与普通互斥锁的区别

from threading import Thread, Lock
import timemoney = 100
mutex = Lock()def task():global moneymutex.acquire()tmp = moneytime.sleep(0.1)money = tmp - 1mutex.release()if __name__ == '__main__':t_list = []for i in range(100):t = Thread(target=task)t.start()t_list.append(t)for t in t_list:t.join()print(money)"""
100个线程起起来之后, 要先去抢GIL
我进入IO GIL自动释放 但我手上还有一个自己的互斥锁
其他线程虽然抢到了但是抢不到互斥锁
最终GIL还是回到自己的手上 自己去操作数据
"""

同一个进程下的多线程无法利用多核优势,是不是就没有了

"""
多线程是否有用要看具体情况
单核:四个任务(IO密集型\计算密集型)
多核:四个任务(IO密集型\计算密集型)
"""
# 计算密集型  每个任务都需要10s
单核(不用考虑)多进程:额外消耗资源多线程:节省开销
多核多进程:总耗时 10+多线程:总耗时 40+
# IO密集型  每个任务都需要10s
多核多进程:相对浪费资源多线程:更加节省资源

代码验证

# 计算机密集型# from threading import Thread
# from multiprocessing import Process
# import time
# import os
#
#
# def work():
#     res = 1
#     for i in range(1, 100000):
#         res *= i
#
#
# if __name__ == '__main__':
#     l = []
#     print(os.cpu_count())
#     start_time = time.time()
#     for i in range(4):
#         # p = Process(target=work)  # 4.017219066619873
#         # p.start()
#         # l.append(p)
#         t = Thread(target=work) # 13.573662042617798
#         t.start()
#         l.append(t)
#     for p in l:
#         p.join()
#     print(time.time() - start_time)# IO密集型
from threading import Thread
from multiprocessing import Process
import time
import osdef work():time.sleep(2)if __name__ == '__main__':l = []print(os.cpu_count())start_time = time.time()for i in range(200):# p = Process(target=work)  # 16.503886699676514# p.start()# l.append(p)t = Thread(target=work) # 2.04239821434021t.start()l.append(t)for p in l:p.join()print(time.time() - start_time)

总结

"""
多进程和多线程都有各自的优势,并且后面写项目的时候通常都是多进程下面再开多线程
这样既可以利用多核要可以节省资源消耗
"""

内容回顾


  • 开启线程的两种方式

    """
    开进程和开启线程的步骤基本都是一样的 只是导入的模块不一样而已
    开进程必须写在main下面而开线程无需这么做类的对象调用方法
    类的继承重写run方法
    """
    
  • TCP服务端实现并发

    """将接客与服务的活分开"""
    
  • 线程对象join方法

    """等待当前线程对象结束之后 再继续往下执行"""
    
  • 同一个进程内的多个数据是共享的

    """
    同一个进程可以开启多个线程
    进程:资源单位
    线程:执行单位
    """
    
  • 线程对象属性和方法

    """
    current_thread.name
    active_count  统计当前正在活跃的线程
    """
    
  • 守护线程

    """
    主线程必须等待所有非守护线程的结束后才能结束
    t.daemon = True
    t.start()
    """
    
  • 线程互斥锁

    """
    当多个线程在操作同一份数据的时候会造成数据错乱
    这个时候为了保证数据安全 通常加锁处理
    锁:将并发变成串行,降低了程序的运行效率但保证了数据安全
    """
    
  • GIL全局解释器锁

    """
    1.GIL是cpython解释器的特点不是python的特点!!!
    2.GIL本质也是一把互斥锁 解释器级别的锁
    3.它的存在是因为cpython解释器内存管理不是线程安全的 
    垃圾回收机制引用技术标记清除分代回收
    4.也就意味着GIL的存在导致了一个进程下的多个线程无法利用多核优势
    5.针对不同的数据应该加不同的锁来处理
    """
    

相关文章:

【线程相关知识】

今日内容概要 开启线程的两种方式TCP服务端实现并发效果线程对象的join方法线程间数据共享线程对象属性及其他方法守护线程线程互斥锁GIL全局解释器锁多进程与多线程的实际应用场景 今日内容详细 开启线程的两种方式 # import time # from multiprocessing import Process #…...

鸿蒙ArkTS声明式开发:跨平台支持列表【透明度设置】 通用属性

透明度设置 设置组件的透明度。 说明: 开发前请熟悉鸿蒙开发指导文档: gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版…...

【SQL学习进阶】从入门到高级应用(九)

文章目录 子查询什么是子查询where后面使用子查询from后面使用子查询select后面使用子查询exists、not existsin和exists区别 union&union alllimit 🌈你好呀!我是 山顶风景独好 💕欢迎来到我的博客,很高兴能够在这里和您见面…...

Web前端三大主流框架技术分享

在当今快速发展的互联网时代,Web前端技术作为连接用户与服务的桥梁,其重要性不言而喻。随着技术的不断进步,为了提升开发效率、优化用户体验,一系列强大的前端框架应运而生。其中,Angular、React和Vue.js作为当前最为主…...

dockers安装mysql

1.dockerhub上搜索自己需要安装得镜像版本 dockerhub网址:https://hub-stage.docker.com docker pull mysql:5.7 #下载自己需要得版本2.启动容器实例,并且挂载容器数据卷 docker run -d -p 3306:3306 --privilegedtrue \ -v /home/mysql/log:/var/log/…...

100道面试必会算法-27-美团2024面试第一题-前缀和矩阵

100道面试必会算法-27-美团2024面试第一题-前缀和矩阵 问题解读 给定一个 n x n 的二进制矩阵,每个元素是 0 或 1。我们的任务是计算矩阵中所有边长为 k 的子矩阵中,包含特定数量 1 的情况。例如,我们希望找到所有边长为 k 的子矩阵中包含 k…...

从摇一摇到弹窗,AD无处不在?为了不再受打扰,推荐几款好用的屏蔽软件,让手机电脑更清爽

当我们沉浸在智能手机带来的便捷与乐趣中时,内置AD如同不速之客,时常打断我们的体验。 尤其是手机上那些“摇一摇”跳转,稍有不慎就会跳转到其他应用,令人不胜其烦。同样,电脑上的内置AD也如影随形,影响了我…...

HackTheBox-Machines--Nibbles

Nibbles 测试过程 1 信息收集 NMAP 80 端口 网站出了打印出“Hello world!”外,无其他可利用信息,但是查看网页源代码时,发现存在一个 /nibbleblog 文件夹 检查了 http://10.129.140.63/nibbleblog/ ,发现了 /index.p…...

东方博宜1703 - 小明买水果

问题描述 小明去超市买了若干斤水果,你能根据水果的单价,小明买的水果数量,编一个程序计算出总金额,并打印出清单。 输入 输入两个值, 第一个为商品的单价,是一个小数。 第二个为商品的数量,…...

mac电脑用谷歌浏览器对安卓手机H5页面进行inspect

1、mac上在谷歌浏览器上输入 chrome://inspect 并打开该页面。 2、连接安卓手机到Mac电脑:使用USB数据线将安卓手机连接到Mac电脑。 3、手机上打开要的h5页面 Webview下面选择要的页面,点击inspect,就能像谷歌浏览器页面打开下面的页面&#…...

动手学深度学习(Pytorch版)代码实践-深度学习基础-01基础函数的使用

01基础函数的使用 主要内容 张量操作:创建和操作张量,包括重塑、填充、逐元素操作等。数据处理:使用pandas加载和处理数据,包括处理缺失值和进行one-hot编码。线性代数:包括矩阵运算、求和、均值、点积和各种范数计算…...

vm-bhyve:bhyve虚拟机的管理系统@FreeBSD

先说情况,当前创建虚拟机后网络没有调通....不明白是最近自己点背,还是确实有难度... 缘起: 前段时间学习bhyve虚拟机,发现bvm这个虚拟机管理系统,但是实践下来发现网络方面好像有问题,至少我花了两天时间…...

【Java】刚刚!突然!紧急通知!垃圾回收!

【Java】刚刚!突然!紧急通知!垃圾回收! 文章目录 【Java】刚刚!突然!紧急通知!垃圾回收!从C语言的内存管理引入:手动回收Java的垃圾回收机制引用计数器循环引用问题 可达…...

[Algorithm][动态规划][子序列问题][最长递增子序列][摆动序列]详细讲解

目录 0.子序列 vs 子数组1.最长递增子序列1.题目链接2.算法原理详解3.代码实现 2.摆动序列1.题目链接2.题目链接3.代码实现 0.子序列 vs 子数组 子序列: 相对顺序是跟源字符串/数组是一致的但是元素和元素之间,在源字符串/数组中可以是不连续的一般时间…...

【稳定检索】2024年心理学与现代化教育、媒体国际会议(PMEM 2024)

2024年心理学与现代化教育、媒体国际会议 2024 International Conference on Psychology and Modern Education and Media 【1】会议简介 2024年心理学与现代化教育、媒体国际会议即将召开,这是一场汇聚全球心理学、教育及媒体领域精英的学术盛宴。 本次会议将深入探…...

深入了解diffusion model

diffusion model是如何运作的 会输入当时noise的严重程度,根据我们的输入来确定在第几个step,并做出不同的回应。 Denoise模组内部实际做的事情 产生一张图片和产生noise难度是不一样的,若denoise 模块产生一只带噪声的猫说明这个模块已经会…...

TransmittableThreadLocal原理

1、原理 TransmittableThreadLocal(简称TTL)是阿里巴巴开源的一个Java库,用于解决线程池中线程本地变量传递的问题。其底层原理主要是基于Java的ThreadLocal机制并对其进行扩展,以支持在父子线程间以及线程池中任务切换时&#x…...

华为昇腾310B初体验,OrangePi AIpro开发板使用测评

0、写在前面 很高兴收到官方的OrangePi AIpro开发板测试邀请,在过去的几年中,我在自己的博客写了一系列有关搭载嵌入式Linux系统的SBC(单板计算机)的博文,包括树莓派4系列、2K1000龙芯教育派、Radxa Rock5B、BeagleBo…...

GPTQ 量化大模型

GPTQ 量化大模型 GPTQ 算法 GPTQ 算法由 Frantar 等人 (2023) 提出,它从 OBQ 方法中汲取灵感,但进行了重大改进,可以将其扩展到(非常)大型的语言模型。 步骤 1:任意顺序量化 OBQ 方法选择权重按特定顺序…...

【GD32】05 - PWM 脉冲宽度调制

PWM PWM (Pulse Width Modulation) 是一种模拟信号电平的方法,它通过使用数字信号(通常是方波)来近似地表示模拟信号。在PWM中,信号的占空比(即高电平时间占整个周期的比例)被用来控制平均输出电压或电流。…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制&#xff0…...

ESP32读取DHT11温湿度数据

芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...