linux高级命令之线程的注意点
线程的注意点
学习目标
能够说出线程的注意点
1. 线程的注意点介绍
线程之间执行是无序的
主线程会等待所有的子线程执行结束再结束
线程之间共享全局变量
线程之间共享全局变量数据出现错误问题
2. 线程之间执行是无序的
import threading
import timedeftask():time.sleep(1)print("当前线程:", threading.current_thread().name)if __name__ == '__main__':for _ in range(5):sub_thread = threading.Thread(target=task)sub_thread.start()
执行结果:
当前线程: Thread-1
当前线程: Thread-2
当前线程: Thread-4
当前线程: Thread-5
当前线程: Thread-3
说明:
线程之间执行是无序的,它是由cpu调度决定的 ,cpu调度哪个线程,哪个线程就先执行,没有调度的线程不能执行。
进程之间执行也是无序的,它是由操作系统调度决定的,操作系统调度哪个进程,哪个进程就先执行,没有调度的进程不能执行。
3. 主线程会等待所有的子线程执行结束再结束
假如我们现在创建一个子线程,这个子线程执行完大概需要2.5秒钟,现在让主线程执行1秒钟就退出程序,查看一下执行结果,示例代码如下:
import threading
import time# 测试主线程是否会等待子线程执行完成以后程序再退出defshow_info():for i in range(5):print("test:", i)time.sleep(0.5)if __name__ == '__main__':sub_thread = threading.Thread(target=show_info)sub_thread.start()# 主线程延时1秒time.sleep(1)print("over")
执行结果:
test: 0
test: 1
over
test: 2
test: 3
test: 4
说明:
通过上面代码的执行结果,我们可以得知: 主线程会等待所有的子线程执行结束再结束
假如我们就让主线程执行1秒钟,子线程就销毁不再执行,那怎么办呢?
我们可以设置守护主线程
守护主线程:
守护主线程就是主线程退出子线程销毁不再执行
设置守护主线程有两种方式:
threading.Thread(target=show_info, daemon=True)
线程对象.setDaemon(True)
设置守护主线程的示例代码:
import threading
import time# 测试主线程是否会等待子线程执行完成以后程序再退出defshow_info():for i in range(5):print("test:", i)time.sleep(0.5)if __name__ == '__main__':# 创建子线程守护主线程 # daemon=True 守护主线程# 守护主线程方式1sub_thread = threading.Thread(target=show_info, daemon=True)# 设置成为守护主线程,主线程退出后子线程直接销毁不再执行子线程的代码# 守护主线程方式2# sub_thread.setDaemon(True)sub_thread.start()# 主线程延时1秒time.sleep(1)print("over")
执行结果:
test: 0
test: 1
over
3. 线程之间共享全局变量
需求:
定义一个列表类型的全局变量
创建两个子线程分别执行向全局变量添加数据的任务和向全局变量读取数据的任务
查看线程之间是否共享全局变量数据
import threading
import time# 定义全局变量
my_list = list()# 写入数据任务defwrite_data():for i in range(5):my_list.append(i)time.sleep(0.1)print("write_data:", my_list)# 读取数据任务defread_data():print("read_data:", my_list)if __name__ == '__main__':# 创建写入数据的线程write_thread = threading.Thread(target=write_data)# 创建读取数据的线程read_thread = threading.Thread(target=read_data)write_thread.start()# 延时# time.sleep(1)# 主线程等待写入线程执行完成以后代码在继续往下执行write_thread.join()print("开始读取数据啦")read_thread.start()
执行结果:
write_data: [0, 1, 2, 3, 4]
开始读取数据啦
read_data: [0, 1, 2, 3, 4]
4. 线程之间共享全局变量数据出现错误问题
需求:
定义两个函数,实现循环100万次,每循环一次给全局变量加1
创建两个子线程执行对应的两个函数,查看计算后的结果
import threading# 定义全局变量
g_num = 0# 循环一次给全局变量加1defsum_num1():for i in range(1000000):global g_numg_num += 1print("sum1:", g_num)# 循环一次给全局变量加1defsum_num2():for i in range(1000000):global g_numg_num += 1print("sum2:", g_num)if __name__ == '__main__':# 创建两个线程first_thread = threading.Thread(target=sum_num1)second_thread = threading.Thread(target=sum_num2)# 启动线程first_thread.start()# 启动线程second_thread.start()
执行结果:
sum1: 1210949
sum2: 1496035
注意点:
多线程同时对全局变量操作数据发生了错误
错误分析:
两个线程first_thread和second_thread都要对全局变量g_num(默认是0)进行加1运算,但是由于是多线程同时操作,有可能出现下面情况:
在g_num=0时,first_thread取得g_num=0。此时系统把first_thread调度为”sleeping”状态,把second_thread转换为”running”状态,t2也获得g_num=0
然后second_thread对得到的值进行加1并赋给g_num,使得g_num=1
然后系统又把second_thread调度为”sleeping”,把first_thread转为”running”。线程t1又把它之前得到的0加1后赋值给g_num。
这样导致虽然first_thread和first_thread都对g_num加1,但结果仍然是g_num=1
全局变量数据错误的解决办法:
线程同步: 保证同一时刻只能有一个线程去操作全局变量 同步: 就是协同步调,按预定的先后次序进行运行。如:你说完,我再说, 好比现实生活中的对讲机
线程同步的方式:
线程等待(join)
互斥锁
线程等待的示例代码:
import threading# 定义全局变量
g_num = 0# 循环1000000次每次给全局变量加1defsum_num1():for i in range(1000000):global g_numg_num += 1print("sum1:", g_num)# 循环1000000次每次给全局变量加1defsum_num2():for i in range(1000000):global g_numg_num += 1print("sum2:", g_num)if __name__ == '__main__':# 创建两个线程first_thread = threading.Thread(target=sum_num1)second_thread = threading.Thread(target=sum_num2)# 启动线程first_thread.start()# 主线程等待第一个线程执行完成以后代码再继续执行,让其执行第二个线程# 线程同步: 一个任务执行完成以后另外一个任务才能执行,同一个时刻只有一个任务在执行first_thread.join()# 启动线程second_thread.start()
执行结果:
sum1: 1000000
sum2: 2000000
5. 小结
线程执行执行是无序的
主线程默认会等待所有子线程执行结束再结束,设置守护主线程的目的是主线程退出子线程销毁。
线程之间共享全局变量,好处是可以对全局变量的数据进行共享。
线程之间共享全局变量可能会导致数据出现错误问题,可以使用线程同步方式来解决这个问题。
线程等待(join)

相关文章:

linux高级命令之线程的注意点
线程的注意点学习目标能够说出线程的注意点1. 线程的注意点介绍线程之间执行是无序的主线程会等待所有的子线程执行结束再结束线程之间共享全局变量线程之间共享全局变量数据出现错误问题2. 线程之间执行是无序的import threading import timedeftask():time.sleep(1)print(&qu…...

MyBatisPlus ---- 多数据源
MyBatisPlus ---- 多数据源1. 创建数据库及表2. 引入依赖3. 配置多数据源4. 创建用户service5. 创建商品service6. 测试适用于多种场景:纯粹多库、读写分离、一主多从、混合模式等 目前我们就来模拟一个纯粹多库的一个场景,其他场景类似 场景说明&#x…...

Java多线程
目录1 多线程1.1 进程1.2 线程1.3 多线程的实现方式1.3.1 方式1:继承Tread类1.3.2 方式2:实现Runnable接口1.3.3 方式3:实现Callable接口1.4 设置和获取线程名称1.5 线程调度1.6 线程控制1.7 线程生命周期1.8 数据安全问题之案例:…...

linux高级命令之线程执行带有参数的任务
线程执行带有参数的任务学习目标能够写出线程执行带有参数的任务1. 线程执行带有参数的任务的介绍前面我们使用线程执行的任务是没有参数的,假如我们使用线程执行的任务带有参数,如何给函数传参呢?Thread类执行任务并给任务传参数有两种方式:args 表示以…...

管理会计报告和财务报告的区别
财务会计报告是给投资人看的,可以反映公司总体的盈利能力。不过,我们回顾一下前面“第一天”里面提到的问题。如果你是公司的产品经理,目前有三个产品在你的管辖范围内。上级给你一笔新的资金,这笔资金应该投到哪个产品上…...
华为OD机试 - 最左侧冗余覆盖子串(Python) | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】 华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】 华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】 华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 …...

【Opencv 系列】第1章 图像基础
通过本套课程,可以学到: 1.opencv的基本操作 2.两个案例,目标追踪&人脸识别 对重点内容,我会提示,包括我再准备这套课程过程中遇到的坑点! 最后代码我会放到git上,章节顺序一致:https://github.com/justinge/opencv_tutorial.git 系列文章目录 第1章 Opencv 图像基础 和 …...
创建和销毁对象——遇到多个构造器参数时要考虑使用构建器
静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。比如用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必需的:每份的含量、每罐的含量以及每份的卡路里。还有超过20个的可选域:总脂肪量、饱和脂…...

【c++学习】入门c++(中)
目录一. 前言二. 函数重载1. 概念2.函数名修饰规则三 .引用(&)1. 概念2. 引用特性3.应用1.做参数2. 做返回值3. 传值、传引用效率比较4.引用和指针的区别四 . 结语一. 前言 小伙伴们大家好,今天我们继续学习c入门知识,今天的…...

论文阅读_AlphaGo_Zero
论文信息 name_en: Mastering the game of Go without human knowledge name_ch: 在没有人类知识的情况下掌握围棋游戏 paper_addr: http://www.nature.com/articles/nature24270 doi: 10.1038/nature24270 date_publish: 2017-10-01 tags: [‘深度学习’,‘强化学习’] if: 6…...
一文教你用Python创建自己的装饰器
python装饰器在平常的python编程中用到的还是很多的,在本篇文章中我们先来介绍一下python中最常使用的staticmethod装饰器的使用。 目录一、staticmethod二、自定义装饰器python类实现装饰器python函数嵌套实现装饰器多个装饰器调用三、带参数的装饰器一、staticmet…...
华为OD机试 - 任务总执行时长(JS)
任务总执行时长 题目 任务编排服务负责对任务进行组合调度。参与编排的任务又两种类型,其中一种执行时长为taskA,另一种执行时长为taskB。任务一旦开始执行不能被打断,且任务可连续执行。服务每次可以编排num个任务。 请编写一个方法,生成每次编排后的任务所有可能的总执…...

pytorch离线快速安装
1.pytorch官网查看cuda版本对应的torch和torchvisionde 版本(ncvv -V,nvidia-sim查看cuda对应的版本) 2.离线下载对应版本,网址https://download.pytorch.org/whl/torch_stable.html 我下载的: cu113/torch-1.12.0%2Bcu113-cp37-cp37m-win_…...
华为OD机试 - 数组合并(JS)
数组合并 题目 现在有多组整数数组,需要将他们合并成一个新的数组。 合并规则,从每个数组里按顺序取出固定长度的内容合并到新的数组中, 取完的内容会删除掉, 如果该行不足固定长度或者已经为空, 则直接取出剩余部分的内容放到新的数组中,继续下一行。 如样例1,获得长度3,先遍…...

不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向
不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向 最近,多所美国高校以及香港大学等都明确禁止在校使用ChatGPT等智能文本生成工具。GPT(Generative Pre-trained Transformer)是一种自然语言处理技术&#x…...

基于matlab的斜视模式下SAR建模
一、前言此示例说明如何使用线性 FM (LFM) 波形对基于聚光灯的合成孔径雷达 (SAR) 系统进行建模。在斜视模式下,SAR平台根据需要从宽侧斜视一定角度向前或向后看。斜视模式有助于对位于当前雷达平台位置前面的区域进行…...

15-基础加强-1-类加载器反射
文章目录1.类加载器1.1类加载器【理解】1.2类加载的过程【理解】1.3类加载的分类【理解】1.4双亲委派模型【理解】1.5ClassLoader 中的两个方法【应用】2.反射2.1反射的概述【理解】2.2获取Class类对象的三种方式【应用】 第1步:获取类的Class对象2.3反射获取构造方…...

基于SSM,Spring, BootStrap 毕业设计管理系统的设计与实现
目录 一.前言介绍 二、主要技术 2.1 SSM框架介绍 2.2 MYSQL数据库 2.3 持久层框架MyBatis 2.4 前端框架BootStrap 三. 系统设计 3.1 系统架构设计 3.2 系统功能模块 3.2.1 学生模块 3.2.2 教师模块 3.2.3 管理员模块 四、数据库设计 4.1 数据分析 4.2 概念设计 …...

一招鉴别真假ChatGPT,并简要介绍ChatGPT、GPT、GPT2和GPT3模型之间的区别和联系
以下内容除红色字体部分之外,其他均来源于ChatGPT自动撰写。 ChatGPT是基于GPT模型的对话生成模型,旨在通过对话模拟实现自然语言交互。它是为了改善人机对话体验而设计的,主要应用于聊天机器人、智能客服等场景。 与GPT模型相比,…...
华为OD机试 - 特异性双端队列(JS)
特异性双端队列 题目 有一个特异性的双端队列,该队列可以从头部到尾部添加数据,但是只能从头部移除数据。 小A一次执行 2n 个指令往队列中添加数据和移除数据, 其中 n 个指令是添加数据(可能从头部也可以从尾部添加) 依次添加 1 到 n , n 个指令是移出数据 现在要求移除数…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...