ThreadLocal是用来做什么的?

真真应了那句话,书读百遍,其意自现。何况大多数时候,你只需要重复一遍就行了,废话不多说。

一,首先来看看这样一些问题的区别:

1. 多进程之间如何通信?

因为不同的进程会在内存中被分配不同的资源。所以多进程之间通信是一个问题,python的multiprocessing模块一共了一系列的交换方式,Queue, Pipe, Manager。

2. 多线程之间如何通信?

这就不是一个问题,因为线程间是共享所在进程变量的。所以通信不是问题,让它们同步才是问题,同步暂且不表。

3. 不同进程间线程如何通信?

这也不是个问题,因为这就是两个进程之间的通信。

4. 一个线程内部如何通信?

可能乍一看,觉得这也能是个问题?但,这才是真正的问题。

二,下面进入正题,看代码

import threading

def a(x):
    print('a thread %d' % x)
    b(x)

def b(x):
    print('b thread %d' % x)

t1 = threading.Thread(target=a, args=(3,))
t2 = threading.Thread(target=a, args=(5,))

t1.start()
t1.join()
t2.start()
t2.join()

Output:
a thread 3
b thread 3
a thread 5
b thread 5

开启线程调用a方法,然后a方法调用b方法。 可以看到,t1,t2两个线程里的x是不同的x。

所以,线程内部两个函数通信,可以用参数来传递。但这显然不是一个好的方法,当函数数量上去或着交互的数据很多,那一层层传参就崩溃了。

那么直接用全局变量?看效果

import threading

x = 0

def a():
    print('a thread %d' % x)
    b()

def b():
    print('b thread %d' % x)

t1 = threading.Thread(target=a)
t2 = threading.Thread(target=a)

t1.start()
t1.join()
t2.start()
t2.join()

Output:
a thread 0
b thread 0
a thread 0
b thread 0

我们的目的是为了让不同的线程,维护不同的x,但是因为x是进程的,所以就只有一份,达不到目的。

三,解决方案

前面达不到目的,是因为进程中的x只有一份,大家都能访问,那么我们在进程中把x做成多份,一个线程对应一份不就行了?那么要实现线程和特定的x一一对应,那就是map了,在python中,使用dict。

import threading

dict = {}

def a(x):
    dict[threading.current_thread()] = x
    print('a thread %d' % x)
    b()

def b():
    print('b thread %d' % dict[threading.current_thread()])

t1 = threading.Thread(target=a, args=(3,))
t2 = threading.Thread(target=a, args=(5,))

t1.start()
t1.join()
t2.start()
t2.join()

Output:
a thread 3
b thread 3
a thread 5
b thread 5

可以看到,在进程中维护了一个dict,然后用每个线程的current_thread()去映射它们各自的x变量。完成了要求。

上面虽然完成了要求,不过怎么看都是野路子,所以ThreadLocal来了。

import threading

dict = threading.local()

def a(x):
    dict.x = x
    print('a thread %d' % dict.x)
    b()

def b():
    print('b thread %d' % dict.x)

t1 = threading.Thread(target=a, args=(3,))
t2 = threading.Thread(target=a, args=(5,))

t1.start()
t1.join()
t2.start()
t2.join()

Output:
a thread 3
b thread 3
a thread 5
b thread 5

其实原理都一样,不过是python做得太好,什么都封装,有些问题看起来就不那么直观了。

猜你喜欢

转载自blog.csdn.net/qq_21294095/article/details/85209523