首页 > 编程语言 >Python多线程

Python多线程

时间:2023-08-26 10:56:13浏览次数:37  
标签:Thread thread Python threading 线程 多线程 target

当进行多线程编程时,涉及到以下几个关键概念和操作

多线程是指在一个进程中同时运行多个线程,每个线程都可以执行不同的任务。线程是操作系统能够进行运算调度的最小单位,它是进程中的一个实体,可以被操作系统独立调度。

以下是与多线程相关的一些核心概念:

1. **进程和线程**:
- 进程(Process)是一个执行中的程序,它拥有独立的内存空间和系统资源。一个进程可以包含多个线程。
- 线程(Thread)是一个轻量级的执行单元,线程在进程内共享内存空间,可以更快地切换和执行。

2. **并发和并行**:
- 并发(Concurrency)是指多个任务交替执行的状态,但不同任务的执行时间可能重叠,侧重于提高资源利用率。
- 并行(Parallelism)是指多个任务同时执行的状态,侧重于提高执行速度。

3. **GIL(Global Interpreter Lock)**:
- 在 CPython(标准的 Python 解释器)中,由于 GIL 的存在,一次只允许一个线程执行 Python 代码。这意味着在多线程环境中,同一时刻只有一个线程能够执行 Python 代码,不同于多核 CPU 上的真正并行。
- GIL 使得 Python 中的多线程在一些 CPU 密集型任务上效率不高,但对于 I/O 密集型任务仍然有优势。

4. **线程同步和竞争条件**:
- 多线程环境下,不同线程可能同时访问共享的资源,可能导致竞争条件(Race Condition),从而导致数据不一致和错误。
- 线程同步机制(如锁、信号量、条件变量等)用于控制多个线程对共享资源的访问,以避免竞争条件。

5. **线程池**:
- 线程池是一种管理和复用线程的技术,它在程序启动时创建一组线程,并将任务分配给这些线程,避免了频繁创建和销毁线程的开销。

多线程适用于以下情况:

- 处理多任务,同时执行多个相对独立的任务。
- 提高程序的响应能力,使用户界面保持活跃,同时后台执行任务。
- 在多核 CPU 上,实现一定程度的并行计算。
- 处理 I/O 密集型任务,如网络通信、文件读写,以充分利用等待的时间。

需要注意的是,多线程编程需要小心处理线程间的竞争条件和同步问题,以避免出现难以调试的问题。在 Python 中,使用 `threading` 模块可以进行多线程编程:

1. **创建多线程**

使用 `threading.Thread` 类可以创建新的线程。通过传递一个函数(或可调用对象)作为参数给线程类,这个函数将成为线程的执行体。

import threading
def worker():
    print("Worker thread")

thread = threading.Thread(target=worker)

2. **主线程**:

主线程是程序启动时默认创建的线程。它是第一个开始执行的线程,通常用于初始化、调度和管理其他线程。

3. **阻塞线程**:

在多线程环境中,有时需要等待其他线程完成某些操作,或者等待一段时间后再继续执行。可以使用 `thread.join()` 方法来阻塞当前线程,直到指定的线程执行完毕。

thread.join()  # 阻塞当前线程,直到 thread 执行完毕

4. **判断线程是否活动**:

使用 `threading.Thread.is_alive()` 方法可以判断一个线程是否处于活动状态(正在执行)。

if thread.is_alive():
    print("Thread is still active")

5. **线程同步**:

在多线程环境中,由于多个线程可能共享相同的资源,可能会导致竞争条件和数据不一致问题。为了避免这些问题,可以使用锁(`threading.Lock`)等同步机制来保护共享资源。

lock = threading.Lock()

def worker():
    with lock:
        # 保护共享资源的代码块

创建多个线程的两种方法:

1. **创建线程实例**

通过创建多个 `threading.Thread` 类的实例来创建多个线程。

thread1 = threading.Thread(target=worker1)
thread2 = threading.Thread(target=worker2)

使用 threading.Thread 类创建多线程时,可以传递一些参数来控制线程的行为和执行。以下是 threading.Thread 构造函数中一些重要参数的含义:

  • target:
    • 这是一个必需的参数,用于指定线程要执行的函数或可调用对象。线程将会运行这个函数。
    • 示例:threading.Thread(target=my_function)
  • args:

    • 这是一个可选参数,是一个元组(tuple),用于传递给目标函数的参数。如果目标函数需要参数,可以使用这个参数进行传递。
    • 示例:threading.Thread(target=my_function, args=(arg1, arg2))
  • kwargs:
    • 这是一个可选参数,是一个字典(dictionary),用于传递给目标函数的关键字参数。
    • 示例:threading.Thread(target=my_function, kwargs={"key1": value1, "key2": value2})
  • name:

    • 这是一个可选参数,用于给线程指定一个名字,以便于标识和区分不同的线程。
    • 示例:threading.Thread(target=my_function, name="MyThread")
  • daemon:

    • 这是一个可选参数,默认为 False。如果设置为 True,则表示将线程设置为守护线程,即主线程退出时会自动终止守护线程,而不管它是否完成。
    • 示例:threading.Thread(target=my_function, daemon=True)
  • group:

    • 这是一个可选参数,用于设置线程组。通常情况下,不需要显式地指定线程组。
  • kwargs:

    • 这是一个可选参数,用于传递额外的关键字参数给 Thread 类的构造函数。

下面是一个示例,演示了如何创建一个带参数的多线程:

import threading

def print_numbers(start, end):
    for i in range(start, end):
        print(i)

thread = threading.Thread(target=print_numbers, args=(1, 6))
thread.start()
thread.join()

 

2. **继承 Thread 类**:

创建一个继承自 `threading.Thread` 类的子类,重写 `run()` 方法,然后通过实例化子类来创建线程。

class MyThread(threading.Thread):
    def run(self):
        # 线程执行的内容

thread1 = MyThread()
thread2 = MyThread()

综合以上概念,以下是一个完整的示例,演示了如何创建多个线程、主线程的行为、阻塞线程、判断线程是否活动以及使用锁进行线程同步:

import threading
import time

def worker():
    print(f"Worker thread started by {threading.current_thread().name}")
    time.sleep(2)
    print(f"Worker thread finished by {threading.current_thread().name}")

lock = threading.Lock()

def synchronized_worker():
    with lock:
        print(f"Synchronized worker thread started by {threading.current_thread().name}")
        time.sleep(2)
        print(f"Synchronized worker thread finished by {threading.current_thread().name}")

thread1 = threading.Thread(target=worker, name="Thread 1")
thread2 = threading.Thread(target=worker, name="Thread 2")

synchronized_thread1 = threading.Thread(target=synchronized_worker, name="Synchronized Thread 1")
synchronized_thread2 = threading.Thread(target=synchronized_worker, name="Synchronized Thread 2")

print("Main thread started")
thread1.start()
thread2.start()

synchronized_thread1.start()
synchronized_thread2.start()

thread1.join()
thread2.join()

synchronized_thread1.join()
synchronized_thread2.join()

print("Main thread finished")

在这个示例中,主线程启动了多个普通线程和带锁的线程。主线程会等待所有线程都完成后再继续执行。注意,在实际编程中,需要根据具体情况使用适当的线程同步机制来保护共享资源。

标签:Thread,thread,Python,threading,线程,多线程,target
From: https://www.cnblogs.com/haonan0827/p/17658472.html

相关文章

  • Python:过滤包含关键字的行
    PythonPandas:根据指定的关键字,过滤(提取)包含该关键字的行,并保存为Excel文件。importpandasaspdimportnumpyasnpinFile=r'D:\教学任务列表(理论课).xlsx'outFile=r'D:\教学任务(统计).xlsx'df1=pd.read_excel(inFile,header=1)type(df1)df1.head()df1.col......
  • python应用耗时分析
    Linuxtimecommandhttps://linuxize.com/post/linux-time-command/粗略分析整个程序的耗时情况。 timewgethttps://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.9.tar.xzWhatwillbeprintedasanoutputdependsontheversionofthetimecommandyou’reu......
  • 【8月摸鱼计划】Python GUI
    总结了一下Python下的图形界面GUI工具,暂时能找到的资料就这么多,后续会补充推荐学习资料。图形界面的定义图形界面图形用户界面(GraphicalUserInterface,简称GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。图形用户界面是一种人与计算机通信的界面显示格式,允许用......
  • 无涯教程-Python - 网络编程
    本章将使您对网络-Socket编程中最著名的概念有所了解。Socket是双向通信通道的端点。Socket可以在一个进程内,同一台机器上的进程之间或不同大陆上的进程之间进行通信。Socket可以在许多不同的通道类型上实现:Unix域Socket,TCP,UDP等。socket库提供用于处理常见传输的特定类以......
  • 用Python制作一个PDF转Word工具
    工具:Python3.9.13,VSCode1.73.1,pdf2docx0.5.6,tkinter,Win10HomePDF文件不易编辑,想要编辑需要转成Word,但网上的工具很多要充VIP,所以今天我们就来做个PDF转Word工具。首先先安装第三方库:pipinstalltkinter导入库:#coding=utf-8importosimporttkinterfrompdf2docximport......
  • 【873】Python读取NetCDF中的scale_factor和add_offset
    参考:python中scale的用法_在netCDF4和Python中使用scale_factor和add_offset的示例?参考代码:importnetCDF4asncdir_path="./2m_temperature/03_TIFF/"files=os.listdir(dir_path)files=sorted(files)forfileinfiles:iffile.find('.tiff')<......
  • Python基础教程06 - 循环
    循环用于重复执行一些程序块。从上一讲的选择结构,我们已经看到了如何用缩进来表示程序块的隶属关系。循环也会用到类似的写法。for循环for循环需要预先设定好循环的次数(n),然后执行隶属于for的语句n次。基本构造是for元素in序列:   statement举例来说,我们编辑一个叫forDemo......
  • 无涯教程-Python - 正则表达示
    正则表达式是特殊的字符序列,可使用模式中保留的特殊语法来帮助您匹配或查找其他字符串或字符串集。Python模块re提供对Python中类似Perl的正则表达式的全面支持。如果在编译或使用正则表达式时发生错误,则re模块会引发异常re.error。Match函数此函数尝试使用可选的标志将RE......
  • 分享一个批量转换某个目录下的所有ppt->pdf的Python代码
    大家好,我是皮皮。一、前言前几天在Python最强王者群【Python小小小白】分享了一份Python自动化办公的代码,可以批量转换某个目录下的所有ppt->pdf,非常强大。二、实现过程在正式跑代码之后,你可能需要按照对应的库,不然会报错。代码运行之后,本地会出现下面的UI界面,选择PPT文件......
  • 学会Python Requests库+Cookies模拟自动登录!
    importrequestsurl="https://my.cheshi.com/user/"headers={"User-Agent":"Mozilla/5.0(Macintosh;IntelMacOSX10_15_7)AppleWebKit/537.36(KHTML,likeGecko)Chrome/116.0.0.0Safari/537.36"}res=requests.get(......