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

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求众数问题实例

    下面是Python求众数问题的完整攻略: 什么是众数? 众数是指在一组数据中出现次数最多的数,例如在数列 1, 2, 3, 3, 3, 4, 4 中,众数是 3。在实际的数据处理过程中,求众数是一项非常常见的任务。 方法一:使用统计函数 Python中有统计函数可以直接帮我们求解众数。 from statistics import mode data = […

    python 2023年5月14日
    00
  • python_mask_array的用法

    Python中mask_array的用法 mask_array是numpy中的一个函数,可以用来创建布尔掩码数组,其中每个元素都会被随机地选择是否被屏蔽(即赋值为False),从而创建一个与原始数组相同形状的数组,其中部分值被屏蔽。 这个函数的主要参数是输入的数组和被屏蔽的比例,默认情况下,比例为50%。例如: import numpy as np arr …

    python 2023年6月5日
    00
  • Python实现自定义异常实例

    下面是Python实现自定义异常实例的完整攻略: 什么是自定义异常 在Python中,异常就是程序执行过程中出现的错误情况。Python内部已经定义了很多的异常类,如TypeError、ValueError、IndexError等等。但是有时候我们需要针对自己的业务需求,自定义一些异常类来提高代码的可读性和可维护性。这就是自定义异常。 如何自定义异常 在Py…

    python 2023年5月13日
    00
  • python错误:AttributeError: ‘module’ object has no attribute ‘setdefaultencoding’问题的解决方法

    当使用Python 2.x版本时,可能会出现”AttributeError: ‘module’ object has no attribute ‘setdefaultencoding'”错误。这是由于Python 2.x中默认的字符集编码是ASCII,而Python 3.x中默认的字符集编码是UTF-8。 解决方法一:在代码文件的开头添加以下内容: impo…

    python 2023年6月3日
    00
  • Python2中文处理纪要的实现方法

    下面是“Python2中文处理纪要的实现方法”的完整攻略。 问题描述 Python2 支持 unicode 编码,但在处理中文字符时可能存在一定的问题,比如: 读取文件时出现乱码。 处理中文字符串时,出现编码错误的情况。 输出中文时,控制台显示的是 Unicode 码点而非中文字符。 … 解决方法 1. 引入编码声明 Python2 默认读取的文件编码是…

    python 2023年5月20日
    00
  • python中tkinter复选框使用操作

    接下来我将为你详细讲解“Python中Tkinter复选框使用操作”的完整攻略,以及两个示例说明。 什么是Tkinter复选框 复选框(Checkbox)是一种用户界面控件,通常用于表示可以选择或取消选择的选项。在Tkinter中,复选框使用Checkbutton控件实现。 如何创建复选框 使用Tkinter创建复选框非常简单,只需要调用Checkbutto…

    python 2023年6月13日
    00
  • 介绍Python中的一些高级编程技巧

    介绍Python中的一些高级编程技巧 Python是一种高级编程语言,具有简单易学、功能强大、可扩展性强等优点因此在各个领域都得到了广泛的应用。为了更好地利用Python的优势,我们需要掌握一些高级编程技巧。以下是介绍Python中的一些高级编程技巧的完整攻略。 1. 使用装饰器增强函数功能 装饰器是一种Python语法,可以在不修改函数源代码的情况下增强函…

    python 2023年5月13日
    00
  • Python标准库sys库常用功能详解

    Python标准库sys库常用功能详解 简介 Python标准库sys库是Python自带的一个系统参数相关的库,通过它可以访问与Python解释器相关的系统参数和函数。它包含了与Python解释器进行交互的一系列工具,主要包括: sys.argv:获取命令行参数 sys.path:获取Python模块搜索路径 sys.modules:获取已经加载的模块 s…

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