python多线程抽象编程模型详解

yizhihongxing

Python多线程抽象编程模型详解

概述

多线程编程是指在同一时间内,有多个线程在同时执行。Python中常用的多线程模块是threading

在多线程编程中,有两种常见的编程模型,即抢占式协作式,Python采用的是协作式的多线程编程模型。

表示线程

在Python中,线程用threading.Thread类表示,创建线程需要实现run方法,此方法中包含线程要执行的代码。

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):
        print("Thread {} started".format(self.num))
        time.sleep(1)
        print("Thread {} stopped".format(self.num))

thread1 = MyThread(1)
thread2 = MyThread(2)
thread1.start()
thread2.start()

创建线程

在Python中创建线程有三种方式,分别是:

  • 使用threading.Thread类创建线程
  • 使用threading.Thread子类化创建线程
  • 使用_thread模块创建线程

使用threading.Thread类创建线程

这是Python中最常见的创建线程的方式。

import threading
import time

def print_time(thread_name, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print("{}: {}".format(thread_name, time.ctime(time.time())))

thread1 = threading.Thread(target=print_time, args=("Thread 1", 2))
thread2 = threading.Thread(target=print_time, args=("Thread 2", 4))
thread1.start()
thread2.start()

使用threading.Thread子类化创建线程

这种方式需要继承并重写threading.Thread类。

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, thread_name, delay):
        threading.Thread.__init__(self)
        self.thread_name = thread_name
        self.delay = delay

    def run(self):
        count = 0
        while count < 5:
            time.sleep(self.delay)
            count += 1
            print("{}: {}".format(self.thread_name, time.ctime(time.time())))

thread1 = MyThread("Thread 1", 2)
thread2 = MyThread("Thread 2", 4)
thread1.start()
thread2.start()

使用_thread模块创建线程

这种方式与threading.Thread类似,但是使用起来相对比较困难,需要直接使用_thread模块的函数。

import _thread
import time

def print_time(thread_name, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print("{}: {}".format(thread_name, time.ctime(time.time())))

try:
    _thread.start_new_thread(print_time, ("Thread 1", 2))
    _thread.start_new_thread(print_time, ("Thread 2", 4))
except:
    print("Error: 无法启动线程")

线程同步

在多线程编程中,为了避免线程之间的互相协调和访问共享资源发生冲突,需要采用线程同步技术。

常用的线程同步技术有:

  • 互斥锁(mutex):一个线程用完临界资源后释放锁,其他等待访问此资源的线程进入临界区执行。
  • 信号量(semaphore):同mutex,不过有多个锁。临界区内最多只能同时运行有限数量的线程。
  • 事件(event):一根线程A触发了一个事件a,另一个线程B可以等待这个事件的发生,并接收该事件发出的信息,从而达到两个线程之间的通信。

互斥锁

互斥锁使用threading.Lock对象实现,可以确保线程互不干扰地访问共享资源。

import threading
import time

class Counter():
    def __init__(self):
        self.value = 0
        self.lock = threading.Lock()

    def increment(self):
        self.lock.acquire()
        try:
            self.value += 1
        finally:
            self.lock.release()

def update_counter(counter):
    for i in range(5):
        time.sleep(0.5)
        counter.increment()
    print("Counter's total value is: {}".format(counter.value))

counter = Counter()
thread1 = threading.Thread(target=update_counter, args=(counter,))
thread2 = threading.Thread(target=update_counter, args=(counter,))
thread1.start()
thread2.start()

信号量

信号量使用threading.Semaphore实现,可以设置允许访问的线程数量。

import threading
import time

class Test:
    def __init__(self, sem):
        self.sem = sem

    def method(self):
        self.sem.acquire()
        print("当前线程:{}".format(threading.current_thread().name))
        time.sleep(1)
        self.sem.release()

sem = threading.Semaphore(3)
tests = [Test(sem) for i in range(10)]
threads = [threading.Thread(target=test.method) for test in tests]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

事件

事件使用threading.Event实现。

import threading
import time

class EventTest:
    def __init__(self, event):
        self.event = event

    def wait_for_event(self):
        print("{} 开始等待事件".format(threading.current_thread().name))
        self.event.wait()
        print("{} 收到事件".format(threading.current_thread().name))

    def send_event(self):
        print("事件马上要处理")
        time.sleep(2)
        print("事件处理完毕")
        self.event.set()

event = threading.Event()
tests = [EventTest(event) for i in range(2)]
threads = [threading.Thread(target=test.wait_for_event) for test in tests] + [threading.Thread(target=test.send_event) for test in tests]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

总结

本文详细介绍了Python多线程抽象编程模型。首先讲解了线程的表示,其次讲解了创建线程的三种方式,接着介绍了线程同步,包括互斥锁、信号量和事件。最后进行了总结,并给出了两个示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python多线程抽象编程模型详解 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Python提取PDF指定内容并生成新文件

    下面我将为你详细讲解如何使用Python提取PDF指定内容并生成新文件的完整攻略。 1. 安装需要的Python库 首先,我们需要安装一些Python库来读取和操作PDF文件。其中,常用的库包括PyPDF2和pdfminer。你可以使用pip命令来安装它们,如下所示: pip install PyPDF2 pip install pdfminer 2. 打开…

    python 2023年5月31日
    00
  • python网络爬虫实战

    Python网络爬虫实战攻略 Python网络爬虫可以帮助我们自动化地从互联网上获取需要的信息,有非常广泛的应用。本攻略基于Python语言,介绍了如何使用Python进行网络爬虫开发,包括爬虫基础知识、网络协议、URL解析、网页解析和数据持久化等内容。 爬虫基础知识 在进行网络爬虫开发前,我们需要掌握一些爬虫基础知识,包括: 网络协议:HTTP、HTTPS…

    python 2023年5月14日
    00
  • 详解Python中datetime库的使用

    详解Python中datetime库的使用 1. datetime库概述 datetime库是Python中处理日期和时间的标准库之一,它提供了多种方便的函数和类,能够方便地完成日期和时间的计算和转换等操作。 2. datetime库结构 datetime库的基本结构包含三个类:date、time和datetime。其中,date类表示日期,time类表示时…

    python 2023年6月2日
    00
  • python数据分析实战指南之异常值处理

    Python数据分析实战指南之异常值处理 异常值的定义 异常值,也称为离群值,是指在一组数据中明显偏离其他数据的数值,可能由数据记录错误或者自然现象造成。在数据分析中,异常值会影响统计分析的准确性,因此需要对其进行处理。 异常值的处理方法 1. 删除异常值 一种常见的处理异常值的方法是直接删除这些异常值。这种方法适用于异常值占比较小的数据集。 import …

    python 2023年5月13日
    00
  • python中的多cpu并行编程

    针对题目要求,我为您详细讲解一下 Python 中的多 CPU 并行编程的完整攻略。 什么是多 CPU 并行编程 多 CPU 并行编程是指利用多个 CPU 同时进行任务处理,以提高程序的执行效率和速度。在 Python 中,多 CPU 并行编程多利用多进程或多线程实现,具体方式可以根据不同场景选择不同的模块或库。 多进程并行编程示例 以下是一个用 multi…

    python 2023年5月19日
    00
  • Python多线程中阻塞(join)与锁(Lock)使用误区解析

    这里是详细的“Python多线程中阻塞(join)与锁(Lock)使用误区解析”的攻略。 什么是多线程中的阻塞和锁 在Python的多线程编程中,阻塞是指等待其他线程完成任务后再继续执行。当一个线程等待另一个线程时,它会被阻塞。这时如果我们不加以处理,就会出现线程依赖、死锁等问题。 锁则是为了保证线程间的同步和互斥,防止多个线程同时访问某一个共享资源。当一个…

    python 2023年5月19日
    00
  • python 用所有标点符号分隔句子的示例

    以下是详细讲解“Python用所有标点符号分隔句子的示例”的完整攻略。 1. 问题描述 在自然语言处理中,将文本分割成句子是一个常见的任务。在Python中,我们可以使用标点符号来分割句子。但是,不同的文本中可能会包含不同的点符号,因此我们使用所有的标点符号来分割句子。 2. 解决方法 在Python中,我们可以使用正则表达式来匹配所有的标点符号,并使用re…

    python 2023年5月14日
    00
  • 如何在Python中对文件进行操作

    当我们需要在Python中读取、写入、删除文件时,我们可以使用一些内置的函数和模块来实现。 打开文件 我们可以使用内置函数open()打开一个文件。open()函数接收两个参数:文件名和模式。模式有很多种,例如读取模式(r)、写入模式(w)、追加模式(a)等等。以下是一些示例: # 以读取模式打开文件 file = open("filename.t…

    python 2023年6月5日
    00
合作推广
合作推广
分享本页
返回顶部