2017-08-10 71 views
0

我是新來的Python,請耐心等待我的問題。訪問線程在不同模塊中的本地對象 - Python

假設我的應用程序有一個名爲message_printer的模塊,它簡單地定義了一個print_message函數來打印消息。現在在我的主文件中,我創建了兩個線程,它們調用message_printer中的print函數。

我的問題是:如何爲每個線程設置不同的消息並在message_printer中訪問它?

message_printer:

import threading 

threadLocal = threading.local() 

def print_message(): 
    name = getattr(threadLocal, 'name', None); 
    print name 
    return 

主:

import threading 
import message_printer 

threadLocal = threading.local() 

class Executor (threading.Thread): 
    def __init__(self, name): 
     threading.Thread.__init__(self) 
     threadLocal.name = name 

    def run(self): 
     message_printer.print_message(); 

A = Executor("A"); 
A.start(); 
B = Executor("B"); 
B.start(); 

這只是輸出NoneNone,而我希望AB。我也嘗試直接訪問print_message函數內的threadLocal對象,但不起作用。

請注意,這只是一個例子。在我的應用程序中,確切的用例是用於日誌記錄。主要啓動一堆調用其他模塊的線程。我想每個線程都有一個不同的記錄器(每個線程都應該記錄到它自己的文件中),並且每個記錄器都需要在Main中配置。所以我試圖實例化每個線程的記錄器,並設置線程本地存儲,然後可以在其他模塊中訪問。

我在做什麼錯?我以此問題爲例Thread local storage in Python

回答

1

您的代碼存在的問題是您沒有將name指派給正確的local()上下文。您的__init__()方法在主線程中運行,然後通過調用.start()啓動AB線程。

您的第一個線程創建A = Executor("A");將創建一個新線程A但更新主線程的本地上下文。然後,當您通過撥打A.start();開始A時,您將輸入A:s上下文,並帶有單獨的本地上下文。這裏沒有定義name,並且最終以None作爲輸出。然後B發生。

換句話說,訪問你應該運行當前線程,你運行.start()(這將調用.run()法)當線程局部變量,但創建的對象不是當(運行__init__())。

獲得當前的代碼的工作,你可以在數據存儲中的每個對象(使用self引用),然後,每個線程運行時,複製內容到線程本地環境:

import threading 

threadLocal = threading.local() 

def print_message(): 
    name = getattr(threadLocal, 'name', None); 
    print name 
    return 

class Executor (threading.Thread): 
    def __init__(self, name): 
     threading.Thread.__init__(self) 
     # Store name in object using self reference 
     self.name = name 

    def run(self): 
     # Here we copy from object to local context, 
     # since the thread is running 
     threadLocal.name = self.name 
     print_message(); 

A = Executor("A") 
A.start() 
B = Executor("B") 
B.start() 

注儘管如此,在這種情況下,使用線程本地上下文有點矯枉過正,因爲我們已經將不同的數據值存儲在不同的對象中。要直接從對象中使用它,需要重寫一次print_message()

+0

太棒了!在我的情況下,我需要訪問存儲在多個地方的不同模塊中的本地線程中的對象。我想避免將它作爲參數傳遞,所以看起來線程本地應該適合我的場景。 – RandomQuestion

相關問題