python线程(python threading模块、python多线程)(守护线程与非守护线程)

文章目录

    • Python多线程入门
      • 1. Python多线程概述
      • 2. `threading`模块基础
        • - Thread 类: 这是一个代表线程的类。可以通过创建`Thread`类的实例来新建一个线程。
        • - Lock 类: 在多线程环境中,为了防止数据错乱,通常需要用到锁机制。`Lock`类提供了基本的锁功能,可以帮助同步线程。
        • - Condition 类: 这是一种更高级的线程同步机制,它在某些条件下阻塞线程,直到被其他线程唤醒。
      • 3. 创建线程
      • 4. 线程间通信
      • 5. 线程同步
    • Python Threading模块各类详解
      • Thread 类
        • - target:指定线程启动时要执行的函数。
        • - args:是一个元组,表示传递给目标函数的参数。
        • - kwargs:是一个字典,表示传递给目标函数的关键字参数。
        • - name:为线程指定一个名称,这在调试时很有用。
        • - daemon:布尔值,指示线程是否是守护线程(守护线程会随着主线程的退出而退出)。
          • 参数
          • 守护线程的特性
          • 示例(守护线程与非守护线程)
            • - 守护线程(主程序退出守护线程将会被强制退出):
            • - 非守护进程(主程序退出,非守护线程照样执行,直到它自己运行完)
        • 示例:
      • Lock 类
        • - acquire(blocking=True, timeout=-1):尝试获得锁。`blocking`参数为`False`时,方法会立即返回一个布尔值,表示是否获取到了锁。`timeout`指定等待锁的最长时间。
        • - release():释放锁。
        • 示例:
      • Semaphore 类
        • - acquire(blocking=True, timeout=-1):同`Lock`的`acquire`。
        • - release():释放信号量。
        • 示例:
      • Event 类
        • - set():将事件状态设置为真。
        • - clear():将事件状态设置为假。
        • - wait(timeout=None):阻塞线程,直到事件的状态为真或超时。
        • 示例:
      • Condition 类
        • - acquire() / release():与Lock相同,用于获取和释放底层锁。
        • - wait(timeout=None):调用线程等待,直到被notify()或notify_all()唤醒或超时。
        • - notify(n=1):唤醒一个或多个正在等待这个条件的线程。`n` 指定要唤醒的线程数。
        • - notify_all():唤醒所有等待这个条件的线程。
        • 示例:
      • Barrier 类
        • - parties:这是Barrier类构造函数的主要参数,代表需要到达屏障点的线程数。只有当指定数量的线程都已调用了wait()方法,所有这些线程才会同时被释放继续执行。这个数字必须在创建Barrier时确定,并在其生命周期内保持不变。
        • - wait():阻塞调用此方法的线程,直到所有线程都已调用此方法。然后所有线程同时释放。
        • 示例:
      • Timer 类
        • - interval:定时器激活之前的延迟时间(秒)。
        • - function:定时器激活时要执行的函数。
        • - args / kwargs:传递给 function 的参数。
        • 示例:
      • 参考文章

Python多线程入门

1. Python多线程概述

Python多线程是一种允许程序同时执行多个任务的技术。它主要通过threading模块实现,该模块提供了丰富的API来创建和管理线程。使用多线程可以提高程序的执行效率,尤其是在执行多个独立的任务时,或者在进行大量的I/O操作时。

2. threading模块基础

threading模块是Python中用于实现多线程的标准库之一。这个模块中包含了多个类和函数,可以帮助开发者创建和管理线程。

- Thread 类: 这是一个代表线程的类。可以通过创建Thread类的实例来新建一个线程。
- Lock 类: 在多线程环境中,为了防止数据错乱,通常需要用到锁机制。Lock类提供了基本的锁功能,可以帮助同步线程。
- Condition 类: 这是一种更高级的线程同步机制,它在某些条件下阻塞线程,直到被其他线程唤醒。

3. 创建线程

创建线程的基本方法是实例化Thread类,它接受一个目标函数和函数的参数。下面是一个简单的示例:

import threading

def print_numbers(n):
    for i in range(1, n + 1):
        print(i)

# 创建线程
thread = threading.Thread(target=print_numbers, args=(10,))
# 启动线程
thread.start()
# 等待线程完成
thread.join()

在这里插入图片描述

这段代码定义了一个打印数字的函数,并在一个新线程中运行这个函数。

4. 线程间通信

线程间的通信可以通过全局变量、队列等方式实现。Python的queue.Queue类是线程安全的,非常适合用来进行线程间的数据传递。

import threading
import queue

# 创建一个队列
q = queue.Queue()

def producer():
    for i in range(10):
        q.put(i)
        print(f"Produced {i}")

def consumer():
    while True:
        item = q.get()
        if item is None:
            break
        print(f"Consumed {item}")
    q.task_done()

# 创建生产者和消费者线程
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)

t1.start()
t2.start()

t1.join()
q.put(None)  # 用None来通知消费者结束
t2.join()

在这里插入图片描述

5. 线程同步

在多线程环境中,线程同步是非常重要的。这可以通过锁(Lock)来实现。下面的示例展示了如何使用锁来确保多个线程可以安全地修改共享数据。

import threading

# 共享资源
counter = 0
lock = threading.Lock()

def update_counter():
    global counter
    with lock:
        current = counter
        current += 1
        counter = current
        print(f"Counter: {counter}")

threads = []
for i in range(10):
    t = threading.Thread(target=update_counter)
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在这里插入图片描述

注意:t.join() 是一个阻塞调用。当在一个线程中调用 join() 方法时,它会阻塞调用它的线程(通常是主线程),直到被 join() 的线程(即 t)执行完毕。这意味着主线程将等待 t 线程结束其执行,然后才继续执行 join() 之后的代码。

join() 方法通常用于确保线程在程序继续执行之前完成其任务,特别是当主线程需要从其他线程中获得结果或确保所有子线程在继续之前完成时。这是一种同步技术,用于协调不同线程间的执行顺序。

这段代码创建了10个线程,每个线程都尝试更新全局变量counter。通过锁lock,确保了每次只有一个线程可以修改counter


确实,之前的回答中只是简要介绍了threading模块的一些基础用法。下面将详细介绍threading模块中几个重要的类和函数,以及它们的参数和用法:

Python Threading模块各类详解

Thread 类

Thread类是threading模块中用来创建和管理线程的主要类。主要参数如下:

- target:指定线程启动时要执行的函数。
- args:是一个元组,表示传递给目标函数的参数。
- kwargs:是一个字典,表示传递给目标函数的关键字参数。
- name:为线程指定一个名称,这在调试时很有用。
- daemon:布尔值,指示线程是否是守护线程(守护线程会随着主线程的退出而退出)。
参数

在 Python 的 threading 模块中,daemon 属性是用来指定线程是否为守护线程(daemon thread)。这个属性接受一个布尔值,用来定义线程的行为:

  • True:线程被设置为守护线程。守护线程在程序退出时不会阻止程序的终止。也就是说,当主程序结束时,所有的守护线程将被强制终止,无论是否运行完成。
  • False:线程被设置为非守护线程(默认值)。非守护线程必须在程序退出前完成或被显式地结束,否则程序会等待这些线程结束后才能完全退出。
守护线程的特性

守护线程通常用于在后台运行的服务或任务,如日志写入、系统监控等。这些任务通常是周期性的,不需要和程序主逻辑同步结束。设置线程为守护线程可以防止这些后台任务延长主程序的生命周期。

示例(守护线程与非守护线程)

下面的代码示例演示了如何设置守护线程,并观察守护线程与非守护线程的行为差异:

- 守护线程(主程序退出守护线程将会被强制退出):
import threading
import time


def daemon_thread():
    while True:
        time.sleep(1)
        print("Daemon thread is running...")


# 创建守护线程
daemon = threading.Thread(target=daemon_thread)
daemon.daemon = True


# 启动线程
daemon.start()


print("Main program exits.")

在这里插入图片描述

- 非守护进程(主程序退出,非守护线程照样执行,直到它自己运行完)
import threading
import time


def non_daemon_thread():
    for i in range(5):
        time.sleep(1)
        print("Non-daemon thread is running...")


# 创建非守护线程
non_daemon = threading.Thread(target=non_daemon_thread)

# 启动线程
non_daemon.start()


print("Main program exits.")

在这里插入图片描述

示例:
import threading

def worker(num):
    """线程执行的目标函数"""
    print(f"Worker: {num}")

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(i,), name=f"thread-{i}")
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在这里插入图片描述

Lock 类

Lock类用于线程同步,主要方法有:

- acquire(blocking=True, timeout=-1):尝试获得锁。blocking参数为False时,方法会立即返回一个布尔值,表示是否获取到了锁。timeout指定等待锁的最长时间。
- release():释放锁。
示例:
import threading

lock = threading.Lock()

def worker(num):
    lock.acquire()
    try:
        print(f"Worker: {num}")
    finally:
        lock.release()

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在这里插入图片描述

Semaphore 类

信号量是一种更高级的同步机制,允许多个线程同时访问相同的资源,但有限制的数量。

- acquire(blocking=True, timeout=-1):同Lockacquire
- release():释放信号量。
示例:
import threading

semaphore = threading.Semaphore(2)

def worker(num):
    with semaphore:
        print(f"Worker: {num}")

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在这里插入图片描述

Event 类

事件是一个简单的同步机制,主要用于线程间的事件通知。

- set():将事件状态设置为真。
- clear():将事件状态设置为假。
- wait(timeout=None):阻塞线程,直到事件的状态为真或超时。
示例:
import threading

event = threading.Event()

def waiter(event, n):
    print(f"Thread {n} waiting for event")
    event.wait()
    print(f"Thread {n} proceeding")

def setter(event):
    print("Setting event")
    event.set()

t1 = threading.Thread(target=waiter, args=(event, 1))
t2 = threading.Thread(target=waiter, args=(event, 2))
t3 = threading.Thread(target=setter, args=(event,))

t1.start()
t2.start()
t3.start()

t1.join()
t2.join()
t3.join()

在这里插入图片描述

当然,threading 模块除了包括 Thread, Lock, Semaphore, 和 Event 类外,还有其他一些有用的同步原语和工具,可以帮助解决线程之间的协调和状态共享问题。下面介绍几个其他常用的类:

Condition 类

Condition类用于复杂的线程同步问题。本质上,它是一个围绕锁(Lock)的更高级的锁,允许一个线程等待某个条件,而让其他线程发出条件已满足的信号。

- acquire() / release():与Lock相同,用于获取和释放底层锁。
- wait(timeout=None):调用线程等待,直到被notify()或notify_all()唤醒或超时。
- notify(n=1):唤醒一个或多个正在等待这个条件的线程。n 指定要唤醒的线程数。
- notify_all():唤醒所有等待这个条件的线程。
示例:
import threading

condition = threading.Condition()

def consumer(cond):
    with cond:
        print("Consumer waiting")
        cond.wait()
        print("Consumer proceed")

def producer(cond):
    with cond:
        print("Producer ready, notifying consumer")
        cond.notify_all()

t1 = threading.Thread(target=consumer, args=(condition,))
t2 = threading.Thread(target=producer, args=(condition,))

t1.start()
t2.start()

t1.join()
t2.join()

在这里插入图片描述

Barrier 类

Barrier类用于创建一个同步点,线程必须同时到达这个点才能继续执行。这在某些并行算法中非常有用,需要所有并行任务同时到达某个计算阶段后才能继续。

- parties:这是Barrier类构造函数的主要参数,代表需要到达屏障点的线程数。只有当指定数量的线程都已调用了wait()方法,所有这些线程才会同时被释放继续执行。这个数字必须在创建Barrier时确定,并在其生命周期内保持不变。
- wait():阻塞调用此方法的线程,直到所有线程都已调用此方法。然后所有线程同时释放。
示例:
import threading

barrier = threading.Barrier(2)

def worker(barrier, num):
    print(f"Worker {num} reaching barrier")
    barrier.wait()
    print(f"Worker {num} passed barrier")

t1 = threading.Thread(target=worker, args=(barrier, 1))
t2 = threading.Thread(target=worker, args=(barrier, 2))

t1.start()
t2.start()

t1.join()
t2.join()

在这里插入图片描述

Timer 类

TimerThread 的子类,用于在指定的时间后启动一个操作。

- interval:定时器激活之前的延迟时间(秒)。
- function:定时器激活时要执行的函数。
- args / kwargs:传递给 function 的参数。
示例:
import threading

def delayed_function():
    print("Timer activated")

timer = threading.Timer(5.0, delayed_function)
timer.start()  # 5秒后,打印输出

在这里插入图片描述

这些类提供了不同的同步机制,使得多线程程序可以更加精细地控制线程间的交互和协调。在设计多线程应用时,了解和选择合适的同步机制是非常重要的,可以帮助避免死锁和竞争条件等问题。


这些类和方法为Python中的多线程编程提供了丰富的支持,使得可以在多种场景下有效地使用线程。


以上内容是对Python多线程的一个基础介绍,涵盖了创建线程、线程间通信和线程同步的基本概念和方法。在实际应用中,根据具体需求选择合适的同步机制和通信方式是非常重要的。

参考文章

参考文章:python线程创建和传参(33)

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

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

相关文章

ArcGIS10.2/10.6安装包下载与安装(附详细安装步骤)

相信从事地理专业的小伙伴来说,应该对今天的标题不会陌生。Arcgis是一款很常用的地理信息系统软件,主要用于地理数据的采集、管理、分析和展示。目前比较常见的版本有ArcGIS 10.2和ArcGIS 10.6。 不可否认,Arcgis具有强大的地图制作、空间分…

第4步CentOS配置SSH服务用SSH终端XShell等连接方便文件上传或其它操作

宿主机的VM安装CENTOS文件无法快速上传,也不方便输入命令行,用SSH终端xshell连接虚拟机的SSH工具就方便多了,实现VM所在宿主机Win10上的xshell能连接vm的centos要实现以下几个环节 1、确保宿主机与虚拟机的连通性。 2、虚拟机安装SSH服务&…

针对Docker容器的可视化管理工具—DockerUI

目录 ⛳️推荐 前言 1. 安装部署DockerUI 2. 安装cpolar内网穿透 3. 配置DockerUI公网访问地址 4. 公网远程访问DockerUI 5. 固定DockerUI公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

AJAX(一)HTTP协议(请求响应报文),AJAX发送请求,请求问题处理

文章目录 一、AJAX二、HTTP协议1. 请求报文2. 响应报文 三、AJAX案例准备1. 安装node2. Express搭建服务器3. 安装nodemon实现自动重启 四、AJAX发送请求1. GET请求2. POST请求(1) 配置请求体(2) 配置请求头 3. 响应JSON数据的两种方式(1) 手动,JSON.parse()(2) 设置…

毕业设计选题:基于ssm+vue+uniapp的校园商铺系统小程序

开发语言:Java框架:ssmuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:M…

分发饼干00

题目链接 分发饼干 题目描述 注意点 1 < g[i], s[j] < 2^31 - 1目标是满足尽可能多的孩子&#xff0c;并输出这个最大数值 解答思路 可以先将饼干和孩子的胃口都按升序进行排序&#xff0c;随后根据双指针 贪心&#xff0c;将当前满足孩子胃口的最小饼干分配给该孩…

旋转矩阵乘法,自动驾驶中的点及坐标系变换推导

目录 1. 矩阵乘法的内项相消 2. 左右乘&#xff0c;内外旋与动静坐标系 3. 点变换 3.1 点旋转后的点坐标表示 3.2 坐标系旋转后的点坐标表示 4. 坐标变换的实质 1. 矩阵乘法的内项相消 关于旋转变换&#xff0c;离不开矩阵的乘法&#xff0c;而矩阵乘法的物理意义和本身数…

[Linux#55][网络协议] 序列化与反序列化 | TcpCalculate为例

目录 1. 理解协议 1.1 结构化数据的传输 序列化与反序列化 代码感知&#xff1a; Request 类 1. 构造函数 2. 序列化函数&#xff1a;Serialize() 3. 反序列化函数&#xff1a;DeSerialize() 补充 4. 成员变量 Response 类 1. 构造函数 2. 序列化函数&#xff1a;…

【软件基础知识】什么是 API,详细解读

想象一下,你正在使用智能手机上的天气应用。你打开应用,瞬间就能看到实时天气、未来预报,甚至是空气质量指数。但你有没有想过,这些数据是如何神奇地出现在你的屏幕上的?答案就在三个字母中:API。 API,全称Application Programming Interface(应用程序编程接口),是现代软件世…

MYSQL面试知识点手册

第一部分&#xff1a;MySQL 基础知识 1.1 MySQL 简介 MySQL 是世界上最流行的开源关系型数据库管理系统之一&#xff0c;它以性能卓越、稳定可靠和易用性而闻名。MySQL 主要应用在 Web 开发、大型互联网公司、企业级应用等场景&#xff0c;且广泛用于构建高并发、高可用的数据…

工程师 - PFM介绍

在电子电路设计中&#xff0c;PFM&#xff08;Pulse Frequency Modulation&#xff0c;脉冲频率调制&#xff09;是一种调制技术&#xff0c;其主要特点是在负载变化时调整脉冲的频率&#xff0c;而保持脉冲的宽度&#xff08;时间长度&#xff09;相对恒定。与PWM&#xff08;…

记忆化搜索专题——算法简介力扣实战应用

目录 1、记忆化搜索算法简介 1.1 什么是记忆化搜索 1.2 如何实现记忆化搜索 1.3 记忆化搜索与动态规划的区别 2、算法应用【leetcode】 2.1 题一&#xff1a;斐波那契数 2.1.1 递归暴搜解法代码 2.1.2 记忆化搜索解法代码 2.1.3 动态规划解法代码 2.2 题二&#xff1…

Transformer预测 | 基于Transformer心率时间序列预测(tensorflow)

效果一览 基本介绍 Transformer预测 | 基于Transformer心率时间序列预测(tensorflow) 程序设计 import pandas as pd from pandas.plotting import lag_plot from statsmodels.graphics

加密与安全_优雅存储二要素(AES-256-GCM )

文章目录 什么是二要素如何保护二要素&#xff08;姓名和身份证&#xff09;加密算法分类场景选择算法选择AES - ECB 模式 (不推荐)AES - CBC 模式GCM&#xff08;Galois/Counter Mode&#xff09;AES-256-GCM简介AES-256-GCM工作原理安全优势 应用场景其他模式 和 敏感数据加密…

AIoT智能工控板

在当今竞争激烈的商业环境中&#xff0c;企业需要强大的科技力量来助力腾飞&#xff0c;AIoT智能工控板就是这样的力量源泉。 其领先的芯片架构设计&#xff0c;使得主板的性能得到了极大的提升。无论是数据的处理速度、图形的渲染能力&#xff0c;还是多任务的并行处理能力&a…

Ceph官方文档_01_Ceph简介

目录 Ceph介绍Ceph介绍 Ceph可用于向云平台提供Ceph对象存储,Ceph可用于向云平台提供Ceph块设备服务。Ceph可用于部署Ceph文件系统。所有Ceph存储群集部署开始都是先设置每个Ceph节点,然后再设置网络。 Ceph存储集群需要以下内容:至少一个Ceph监视器和至少一个Ceph管理器,…

毕业设计选题:基于ssm+vue+uniapp的捷邻小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

Linux top命令详解与重点内容说明

文章目录 重点说明基本信息进程(任务)信息cpu占用信息%Cpu(s)内存信息交换内存信息每列含义说明交互命令多窗口模式颜色配置命令参数 重点说明 top命令非常强大&#xff0c;也非常复杂&#xff0c;很难面面俱到&#xff0c;也没有必要&#xff0c;这篇文章的目的是介绍重点&am…

en造数据结构与算法C# 群组行为优化 和 头鸟控制

实现&#xff1a; 1.给鸟类随机播放随机动画使得每一只鸟扇翅膀的频率都不尽相同 2.可以自行添加权重&#xff0c;并在最后 sumForce separationForce cohesionForce alignmentForce;分别乘上相应权重&#xff0c;这样鸟就能快速飞行和转向辣 using System.Collections.Ge…

Linux系统编程(基础指令)上

1.Linux常见目录介绍 Linux目录为树形结构 /&#xff1a;根目录&#xff0c;一般根目录下只存放目录&#xff0c;在Linux下有且只有一个根目录。所有的东西都是从这里开始。当你在终端里输入“/home”&#xff0c;你其实是在告诉电脑&#xff0c;先从/&#xff08;根目录&…