[Python 多线程] threading.local类 (六)

在使用threading.local()之前,先了解一下局部变量和全局变量。

局部变量:

import threading
import time

def worker():
    x = 0
    for i in range(100):
        time.sleep(0.0001)
        x += 1
    print(threading.current_thread(),x)

for i in range(10):
    threading.Thread(target=worker).start()

运行结果:
<Thread(Thread-2, started 123145372971008)> 100
<Thread(Thread-6, started 123145393991680)> 100
<Thread(Thread-1, started 123145367715840)> 100
<Thread(Thread-3, started 123145378226176)> 100
<Thread(Thread-5, started 123145388736512)> 100
<Thread(Thread-7, started 123145399246848)> 100
<Thread(Thread-4, started 123145383481344)> 100
<Thread(Thread-10, started 123145415012352)> 100
<Thread(Thread-8, started 123145404502016)> 100
<Thread(Thread-9, started 123145409757184)> 100

  上面例子使用多线程,每个子线程完成不同的计算任务,x是局部变量。

每个子线程都要压栈,每个栈是独立的空间。每次压栈,局部变量x的作用域地址是不同的(线程独享),计算结果互不干扰。

全局变量:

使用global:

import threading
import time

x = 0
def worker():
    global x
    x = 0
    for i in range(100):
        time.sleep(0.0001)
        x += 1
    print(threading.current_thread(),x)

for i in range(10):
    threading.Thread(target=worker).start()

运行结果:
<Thread(Thread-2, started 123145483571200)> 888
<Thread(Thread-5, started 123145499336704)> 908
<Thread(Thread-3, started 123145488826368)> 930
<Thread(Thread-4, started 123145494081536)> 937
<Thread(Thread-1, started 123145478316032)> 941
<Thread(Thread-6, started 123145504591872)> 947
<Thread(Thread-7, started 123145509847040)> 949
<Thread(Thread-8, started 123145515102208)> 955
<Thread(Thread-9, started 123145520357376)> 962
<Thread(Thread-10, started 123145525612544)> 964

  上面例子中当主线程中x是全局变量时,就变成了公共资源(也就是同一个对象),每个子线程互相干扰,最终导致错误的计算结果。

Python提供了 threading.local 类,将这个类实例化得到一个全局对象,但是不同的线程使用这个对象存储的数据其它线程不可见(本质上就是不同的线程使用这个对象时为其创建一个独立的字典)。

使用threading.local() :

import threading
import time

# class A:
#     def __init__(self,x):
#         self.x = x
# a = A(0)

a = threading.local()#全局对象

def worker():
    a.x = 0
    for i in range(100):
        time.sleep(0.0001)
        a.x += 1
    print(threading.current_thread(),a.x)

for i in range(10):
    threading.Thread(target=worker).start()

运行结果:
<Thread(Thread-4, started 123145570172928)> 100
<Thread(Thread-6, started 123145580683264)> 100
<Thread(Thread-1, started 123145554407424)> 100
<Thread(Thread-2, started 123145559662592)> 100
<Thread(Thread-8, started 123145591193600)> 100
<Thread(Thread-5, started 123145575428096)> 100
<Thread(Thread-3, started 123145564917760)> 100
<Thread(Thread-7, started 123145585938432)> 100
<Thread(Thread-10, started 123145601703936)> 100
<Thread(Thread-9, started 123145596448768)> 100

  每个子线程使用全局对象a,但每个线程定义的属性a.x是该线程独有的。

举一个错误的例子:,主线程中使用threading.local定义本地变量x,x在主线程中是独有的,子线程中就访问不到主线程的x的属性。

import threading

X=‘abc‘
ctx=threading.local()
ctx.x=123 #主线程中定义x本地属性
print(ctx,type(ctx),ctx.x)

def work():
    print(X)
    print(ctx)
    print(ctx.x) #子线程访问不到
    print(‘Good job‘)

threading.Thread(target=work).start()
运行结果:
<_thread._local object at 0x10407bd00> <class ‘_thread._local‘> 123
abc
<_thread._local object at 0x10407bd00>
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Users/ihoney/Python/test_4.py", line 12, in work
    print(ctx.x)
AttributeError: ‘_thread._local‘ object has no attribute ‘x‘

  ctx全局对象对主线程和子线程都是可以使用的,主线程定义了属性x,但子线程在尝试访问属性x时,就相当于访问自己线程内的属性x,而自己线程并没有定义,就会抛出AttributeError异常:‘_thread._local‘ object has no attribute ‘x‘。

时间: 2024-10-11 11:45:59

[Python 多线程] threading.local类 (六)的相关文章

Python 多线程threading模块

首先,我们在了解多线程时需要理解的就是什么是多线程,按照官方的解释就是:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术. 在我自学到这里的时候,通过会在想进程和线程到底是有什么区别,我的理解就是: 进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,一个进程可以包含多个线程. 下面就以简单的例子来加强我们对python 线程的理解. 默认情况下,我们在没有启动线程的时候,可以看一下程序总的运行时间,应该是每个函数

再看python多线程------threading模块

现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个","否则会抛参数异常的错误. 如下: 1 for i in xrange(5): 2 threads.append(threading.Thread(target=worker,args=(i,))) 2.关于join()阻塞 join()方法一旦被调用,这个线程就会被阻塞住,等其他线程执行完才执行自身.当我们在主线程A中,创建了n个子线

python多线程-threading模块

threading 是我们常用的用于 python 多线程的模块,其功能更加丰富.下面我们就来开始学习这个模块. 同样的,我这里声明一样我使用的版本是 python2.7,不同版本直接可能存在差异. 老规矩,使用 help() 函数获取帮助文档,看看里面有什么内容. threading 模块中提供了一个 thread 的类,注意不要和 thread 模块搞混了,两者差别还是很大的.thread 这个类可以实例化一个对象,每个对象代表一个线程,可以调用其中的 run() 方法来开启一个线程的运行.

Python中threading.local方法

#coding=utf-8 import threading # 创建全局ThreadLocal对象: localVal = threading.local() localVal.val = "Main-Thread" def process_student(): print '%s (in %s)' % (localVal.val, threading.current_thread().name) def process_thread(name): #赋值 localVal.val

多线程threading.local的作用?

1.作用: 内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值.保证线程之间的数据隔离. { 线程ID: {...} 线程ID: {...} 线程ID: {...} 线程ID: {...} } 2.示例: import time import threading v = threading.local() def func(arg): # 内部会为当前线程创建一个空间用于存储:phone=自己的值 v.phone = arg time.sleep(2) # 去当前线程自己空间取值

Python多线程threading用法

Python里面经常会用到多线程,即所有的方法在同一时间开始运行,而不是按顺序一个一 个运行.所用到的模块为threading,下面详解threading用法. 我们写三个方法,one.two.three并正常运行. 这里只截图了one()方法,two.three与one内容一样. 按下面图中的运行方式,三个函数是分别在不同时间运行的. 我们用threading使三个方法在同一时间运行   定义一个线程池并把要运行的线程都写到这个线程池列表里: threads= [] #定义一个线程池t1 =

PYTHON——多线程:Thread类与线程函数

Thread类与线程函数 可以使用Thread对象的join方法等待线程执行完毕:主线程(main()函数)中调用Thread对象的join方法,并且Thread对象的线程函数没有执行完毕,主线程会处于阻塞状态.使用Thread类实现多线程的步骤:1.创建Thread类的实例:2.通过Thread类的构造方法的target关键字参数执行线程函数:通过args关键字参数指定传给线程函数的参数.3.调用Thread对象的start方法启动线程.下面例子功能:使用Thread对象启动2个线程,并在各自

Python多线程threading

介绍 在Python中,使用多线程multi-threading可以『同时』执行多个任务,比如你需要一个线程来复制读取信息,另一个线程来解析.为什么这里的同时要加引号呢,这是由于Python中GIL,也就是全局锁,看似同时执行多个任务,实际上是分布执行的,只不过各自完成不同的任务会提高工作效率.如果你不了解GIL,请看下图 实例教程 实例1 import threading def job(): info = "this is an added thread, which is %s"

Python 多线程 threading

#!/usr/bin/python # -*- coding: utf-8 -*- __author__ = 'gaogd' ''' ### 多进程 import threading import time def run(num):     print 'Hi, I am thread %s..lalala' % num     time.sleep(1) for i in range(20):   t = threading.Thread(target=run, args=(i,))   t