16.Python多线程

如果想让我们的程序同时执行多个任务,就需要使用多线程技术了 。到目前为止,我们编写的程序都是单线程的,在运行时一次只能执行 一个任务。

1 线程相关的知识

1.1 进程

一个进程就是一个正在执行的程序,每一个进程都有自己独立的一 块内存空间、一组系统资源。在进程的概念中,每一个进程的内部数据 和状态都是完全独立的。

在Windows操作系统中,一个进程就是一个exe或者dll程序,它们 相互独立,相互也可以通信。

1.2 线程

在一个进程中可以包含多个线程,多个线程共享一块内存空间和一 组系统资源。所以,系统在各个线程之间切换时,开销要比进程小得多 ,正因如此,线程被称为轻量级进程。

1.3 主线程

Python程序至少有一个线程,这就是主线程,程序在启动后由Pytho n解释器负责创建主线程,在程序结束后由Python解释器负责停止主线 程。

在多线程中,主线程负责其他线程的启动、挂起、停止等操作。其 他线程被称为子线程。

2 线程模块——threading

Python官方提供的threading模块可以进行多线程编程。threading模 块提供了多线程编程的高级API,使用起来比较简单。

在threading模块中提供了线程类Thread,还提供了很多线程相关的 函数,这些函数中常用的如下。

active_count():返回当前处于活动状态的线程个数。

current_thread():返回当前的Thread对象。

main_thread():返回主线程对象。主线程是Python解释器启动的 线程。示例代码如下:

3 创建子线程

创建一个可执行的子线程,需要如下两个要素。

1 线程对象:线程对象是threading模块的线程类Thread或Thread子 类所创建的对象。

2 线程体:线程体是子线程要执行的代码,这些代码会被封装到一 个函数中。子线程在启动后会执行线程体。实现线程体主要有以下两种 方式。

1)自定义函数实现线程体。

2)自定义线程类实现线程体。

3.1 自定义函数实现线程体

创建线程Thread对象的构造方法如下:

target参数指向线程体函数,我们可以自定义该线程体函数;通过n ame参数可以设置线程名,如果省略这个参数,则系统会为其分配一个 名称;args是为线程体函数提供的参数,是一个元组类型。 示例代码如下:

3.2 自定义线程类实现线程体

另外一种实现线程体的方式是,创建一个Thread子类并重写run() 方法,run()方法就是线程体函数。

采用自定义线程类重新实现16.3.1节的示例,示例代码如下:

4 线程管理

线程管理包括线程创建、线程启动、线程休眠、等待线程结束和线 程停止,其中,线程创建、线程启动和线程休眠在3节已经用到了, 这些不再赘述。本节重点介绍等待线程结束和线程停止的内容。

4.1 等待线程结束

有时,一个线程(假设是主线程)需要等待另外一个线程(假设是 t1子线程)执行结束才能继续执行。

4.2 线程停止

在线程体结束时,线程就停止了。但在某些业务比较复杂时,会在 线程体中执行一个“死循环”。线程体是否持续执行“死循环”是通过判断 停止变量实现的,“死循环”结束则线程体结束,线程也就结束了。

另外,在一般情况下,死循环会执行线程任务,然后休眠,再执行 ,再休眠,直到结束循环。

通过Python指令运行文件:

5 动动手——下载图片示例

这个网络爬虫程序每隔一段时间都会执行一次下载图片任务,在下 载任务完成后,休眠一段时间再执行。这样反复执行,直到爬虫程序停 止。

示例参考代码如下:

本示例从服务器下载图片,因此需要参考14.2节启动Web服务器, 然后通过Python指令运行文件。

6 练一练

1 请简述如何创建线程体。

2 请简述线程中join()方法的作用。

3 下列哪些情况可以停止当前线程的运行?()

A.引发一个异常时。

B.当该线程调用sleep()方法时。

C.当创建一个新线程时。

D.当该线程调用stop()方法时。

4 判断对错(请在括号内打√或×,√表示正确,×表示错误)。

1)线程对象是threading模块线程类Thread或Thread子类所创建的对 象。()

2)实现线程体主要有以下两种方式:自定义函数实现线程体和自 定义线程类实现线程体。()

3)在线程体结束时,可通过调用stop()方法停止。()

4)在线程体结束时,可通过调用join()方法停止。()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/510558.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 基础复习

1.常量 #include<iostream> using namespace std; // 1.define 宏常量 #define N 50 int main(){//N 60; // define定义的数据为常量&#xff0c;一旦修改会报错 cout<<N<<endl;//2.const 修饰的常量 const int m 12; //m 24; //错误 const修饰的常量不能…

限速虚量就赔一万元?看我如何薅羊毛!2024公认最好的随身WiFi

作为一个大名鼎鼎的羊毛党&#xff0c;最热衷的莫过于网上各种可以薅羊毛的信息。这天我们的羊毛群里说有一个叫格行的随身WiFi品牌挺嚣张的&#xff0c;号称限速虚量就赔付一万元&#xff01;还发了带章的承诺函&#xff01;我心说随身WiFi限速虚量的臭名声早就烂大街了&#…

基本电路理论-电流和电压的参考方向

&#x1f308;个人主页&#xff1a;会编程的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 电流及参考方向 电流&#xff1a;带电粒子有规则的定向移动 电流强度&#xff1a;单位时间内通过导体横截面的电荷量&#xff0c;即&#xff1a;idq/dt 单位&#xff1a…

【C++】lambda 表达式 / 包装器 / bind 绑定

目录 一. lambda 表达式1. lambda 表达式的语法1. lambda 表达式的使用2. lambda 表达式的捕捉列表 二. 包装器三. bind 绑定 一. lambda 表达式 Lambda 表达式是 C11 标准引入的一种新特性, 它提供了一种方便的方式来定义匿名函数. lambda 表达式实际上是一个匿名的仿函数; …

ZYNQ学习之Ubuntu下Linux文件系统、用户权限与磁盘管理

基本都是摘抄正点原子的文章&#xff1a;<领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 一、Linux 文件系统 1.1 Linux 文件系统简介以及类型 操作系统的基本功能之一就是文件管…

SpringBoot快速入门笔记(1)

文章目录 一、环境准备1、maven2、新建项目版本问题 二、项目上手1、HelloController2、热部署3、控制器4、参数传递5、ParamsController 一、环境准备 1、maven 把下载的maven包给配置好 2、新建项目版本问题 新建项目发现没有Java8&#xff0c;新版本IDEA问题&#xff08;2…

JAVA基础02-Java语言基础以及编译准备工作

什么是JAVA语言 Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和简单易用的两个特征。 &#xff08;可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式…

HTTPS跟HTTP有区别吗?

HTTPS和HTTP的区别&#xff0c;白话一点说就是&#xff1a; 1. 安全程度&#xff1a; - HTTP&#xff1a;就像是你和朋友面对面聊天&#xff0c;说的话大家都能听见&#xff08;信息明文传输&#xff0c;容易被偷听&#xff09;。 - HTTPS&#xff1a;就像是你们俩戴着加密耳机…

idea 报错 Could not list the contents of folder “ftps

idea 报错 Could not list the contents of folder "ftps 解决方案 这里看到了网上的解决方案&#xff0c;顺便再记录一下。打开 【高级】菜单 - 取消勾选 被动模式。然后点击测试连接&#xff0c;显示连接成功&#xff01; ftp中的主动模式和被动模式 主动模式&…

嵌入式MCU和SOC之间的区别是什么?

今日话题&#xff0c;嵌入式MCU和SOC之间的区别是什么&#xff1f;表面上看&#xff0c;MCU代表嵌入式微控制器&#xff0c;而SOC代表片上系统&#xff0c;似乎只是嵌入式系统的不同称谓。然而&#xff0c;在实际的研发和产品设计中&#xff0c;你会发现它们在软硬件层面存在显…

【Python项目】基于django的【医用耗材网上申领系统】

医院信息化是社会发展的一个重要标志&#xff0c;它涉及到医院的各个方面&#xff0c;包括人员和物资&#xff0c;因此受到社会各界的广泛关注。近年来&#xff0c;随着医疗耗材数量的不断增加&#xff0c;如何有效管理这些耗材已经成为管理人员、医生以及社会各方面共同面临的…

数据结构(初阶)第二节:顺序表

从本文正式进入对数据结构的讲解&#xff0c;开始前友友们要有C语言的基础&#xff0c;熟练掌握动态内存管理、结构体、指针等章节&#xff0c;方便后续的学习。 顺序表&#xff08;Sequence List&#xff09; 线性表的概念&#xff1a;线性表&#xff08;linear list&#xff…

C++初阶:模拟实现vector类

模拟实现vector类 实现代码:vector.h #pragma once #include<assert.h> #include<iostream> using namespace std;namespace bit {template<class T>class vector{public:// Vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_ite…

网络升级固件

资源信息 可知 &#xff1a; install\soc_cv1800b_milkv_duo_sd\boot.sd文件较设备中的同名文件多了128个字节的文件头&#xff1b;install\soc_cv1800b_milkv_duo_sd\rawimages\boot.sd文件与设备中同名文件相同&#xff1b; 环境搭建 服务器 启动TFTP服务 安装TFTP服务器…

vue2项目安装(使用vue-cli脚手架)

使用npm安装 安装镜像&#xff08;使npm创建项目更快&#xff09;&#xff1a;镜像可更换 npm config set registry https://registry.npmmirror.com1.全局安装vue-cli&#xff08;一次&#xff09; npm install -g vue/cli 2. 查看vue-cli 版本 vue --version 3. 创建项目…

Redis的安装部署

目录 1、关闭防火墙 2、yum安装gcc依赖包 3、提前准备好安装包并解压在opt目录下 4、进入redis目录下进行make编译 5、选择用于安装的目录 6、执行软件包提供的 install_server.sh 脚本文件设置 Redis 服务所需要的相关配置文件 7、一直回车直到出现以下提示 8、 把redi…

Java进阶-反射的详解与应用

本文深入探讨了Java反射机制的核心概念、应用实例及其在现代Java开发中的重要性。文章首先介绍了反射的基本原理和能力&#xff0c;包括在运行时动态获取类信息、操作对象字段和方法的能力。随后&#xff0c;通过具体代码示例&#xff0c;展示了如何利用反射进行字段访问、方法…

【嵌入式智能产品开发实战】(十四)—— 政安晨:通过ARM-Linux掌握基本技能【链接静态库与动态库】

目录 链接静态库 动态链接 与地址无关的代码 全局偏移表 延迟绑定 共享库 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式智能产品开发实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论…

6.7物联网RK3399项目开发实录-驱动开发之Camera摄像头的使用(wulianjishu666)

90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接&#xff1a;https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f Camera 使用 简介 AIO-3399J 开发板分别带有两个 MIPI&#xff0c;MIPI 支持最高 4K 拍照&#xff0c;并支持 1080P 30fp…

ecology9.0通过自定义按钮给明细表某字段赋值

功能&#xff1a;把主表字段赋值给明细表字段 核心代码&#xff1a; <script>jQuery(document).ready(function(){$(#setcgy).click(function(){var cgy_txt WfForm.getBrowserShowName("field1207");debuggervar cgy WfForm.getFieldValue("field1207…