python - 何时在 Python 中使用线程本地内存?

标签 python multithreading python-multithreading

我刚从 Python 开始,偶然发现了线程本地内存。我写了一个使用线程的小程序:

#!/usr/bin/env python3

import logging
import signal
import threading
import time

class WorkerThread(threading.Thread):
    def __init__(self, idx):
        threading.Thread.__init__(self)
        self.thread_index = idx
        self.thread_alive = True

    def run(self):
        logging.info(f'Thread {self.thread_index} is starting up!')

        while self.thread_alive:
            logging.info(f'Thread {self.thread_index} is still running.')
            time.sleep(1)

        logging.info(f'Thread {self.thread_index} is stopping!')

    def kill(self):
        self.thread_alive = False

def main():
    logging.basicConfig(format = '%(levelname)s: %(message)s', level = logging.INFO)

    def signal_handler(sig, frame):
        logging.info('Ctrl+c pressed, killing threads and shutting down ...')
        nonlocal threads
        for thread in threads:
            thread.kill()

    signal.signal(signal.SIGINT, signal_handler)

    logging.info('Signal handler registered, starting threads ...')

    threads = []
    for i in range(0, 3):
        thread = WorkerThread(i)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    signal.signal(signal.SIGINT, signal.SIG_DFL)

if __name__ == '__main__':
    main()
该程序按预期工作并打印如下内容:
> python3 main.py
INFO: Signal handler registered, starting threads ...
INFO: Thread 0 is starting up!
INFO: Thread 0 is still running.
INFO: Thread 1 is starting up!
INFO: Thread 2 is starting up!
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
INFO: Thread 2 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 1 is still running.
INFO: Thread 0 is still running.
INFO: Thread 1 is still running.
INFO: Thread 2 is still running.
INFO: Thread 0 is still running.
^CINFO: Ctrl+c pressed, killing threads and shutting down ...
INFO: Thread 2 is stopping!
INFO: Thread 1 is stopping!
INFO: Thread 0 is stopping!
在这种情况下,thread_indexthread_alive变量特定于每个线程,因为它们特定于每个对象。但也有threading.local()创建 thread local memory 的函数.所以我尝试使用它,因为我希望我的变量是线程特定的。我在定义类后使用它:
# imports and shebang

class WorkerThread(threading.Thread):
    thread_index = threading.local()
    thread_alive = threading.local()

# everything else stays the same
但是使用它不会改变任何东西,输出保持不变。所以我的问题是:
  • 这个线程本地内存是用于另一个用例还是第一个程序只是偶然工作?
  • threading.local() 的用例是什么? ,因为创建对象特定(非静态)变量似乎也有效?
  • 最佳答案

    threading.local()适用于您不能或不想修改实现线程的类的情况。
    在上面的示例中,您可以完全控制,因为您已经创建了 WorkerThread。你已经开始线程了。因此,您知道每个正在运行的线程都有一个实例,并且您可以将值存储在绑定(bind)到线程的实例中。这就是您最初的示例有效的原因。它在这方面工作正常。
    但控制线程并不总是如此。有时线程由库或框架启动,您只提供将在这些线程中运行的一些代码。在这种情况下,您不能修改 Thread类并向它们添加线程特定的变量。
    让我们以多线程 Web 服务器为例。您提供应该处理传入请求的函数。您无需创建所有基础设施来监听套接字、解析 http 请求等。所有这些事件都由框架处理。它为您启动一个线程池,当有传入请求时,框架会解析它并使用池中的线程调用您提供的处理程序。
    在这种情况下,假设您想为正在处理的请求(例如当前登录的用户)存储一些上下文,以便您可以在请求处理期间访问它,但不需要在每个函数中显式地传递它。您不能添加此 currentUser变量到线程类,因为您无法控制它。但是你可以使用 threading.local()存储它。在多个线程中同时处理的请求将拥有自己的副本。
    这同样适用于您自己的创作。当程序变得更复杂并且您需要将基础架构代码(管理线程)与应用程序的逻辑分开时,您可能不想将线程特定变量添加到线程类并使用 threading.local()反而。

    关于python - 何时在 Python 中使用线程本地内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64157133/

    相关文章:

    python - 将多个函数应用于多个 groupby 列

    java - Java 和 Python 可以共存于同一个应用程序中吗?

    python - Snakebite HDFS touchz 不工作

    android - 独立工作线程还是 IntentService?

    c# - 线程/线程池或后台 worker

    python - python threading.Lock() 是否锁定所有需要锁定的东西?

    Python 多处理池与多处理线程池

    java - 线程 "something thread"java.lang.OutOfMemoryError : Java heap space. 中的异常我该怎么办?

    python - 如何在不浪费太多 cpu 周期的情况下等到多线程队列不为空

    sqlite - 如何通过多处理传递sqlite连接对象