gpt4 book ai didi

Python: 'thread._local object has no attribute ' 待办事项'

转载 作者:太空宇宙 更新时间:2023-11-03 14:31:47 24 4
gpt4 key购买 nike

我目前正在使用线程和所有这些编写基于 python 的数据报服务器。

我遇到了以下问题:我正在使用多个分配线程将传入的包分配给不同的处理线程。在处理线程中,我使用 threading.local() 来跟踪线程局部变量。

我目前正在测试我的服务器在高负载期间的 react (约 2 秒内 2000 个数据包),并且发现了 local()-Object 的奇怪行为。

它似乎在一段时间内工作得很好,然后,在某个时刻,它抛出了一个异常:

Exception in thread 192.168.1.102: # <-- This is the Processing Thread
Traceback (most recent call last):
File "/opt/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/volume1/home/Max/Python/MyThread/pyProcThread.py", line 37, in run
print self.loc.father
AttributeError: 'thread._local' object has no attribute 'father'

# The following three lines are debug
# This is the Allocation thread that has called the Processing thread
<Thread(192.168.1.102, started 1106023568)>
# This confirms that the queue it tries to access exists
<Queue.Queue instance at 0x40662b48>
# This is the Processing thread, which has stopped executing on exception
<Thread(192.168.1.102, stopped 1106023568)>

Exception in thread pyAlloc-0: # <-- This is the Allocation thread
Traceback (most recent call last):
File "/opt/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/volume1/home/Max/Python/MyThread/pyAllocThread.py", line 60, in run
foundThread.addTask(str(data))
File "/volume1/home/Max/Python/MyThread/pyProcThread.py", line 58, in addTask
print self.loc.todo
AttributeError: 'thread._local' object has no attribute 'todo'

处理线程的一部分

# Imports
import threading
import time
import Queue

class Thread(threading.Thread):
def __init__(self,pThread):
threading.Thread.__init__(self)
self.loc = threading.local()
self.loc.todo = Queue.Queue()
self.loc.father = pThread
print "Konstruktor ausgefuehrt"
print self.loc.todo

def run(self):
self.loc.run = True;
print self.loc.father
while (self.loc.run):
try:
task = self.loc.todo.get(True, 1)
print "processing..."
if(task == self):
self.loc.run=False
else:
print task
except Queue.Empty:
pass
self.loc.father.threadTerminated(self)
print self.name, "terminating..."

def addTask(self, pTask):
print self
print self.loc.todo
self.loc.todo.put(pTask)

和分配线程:

import threading
import pyProcThread # My processing Thread
import Queue
import time
class Thread(threading.Thread):
# Lock-Objects
threadListLock = threading.Lock()
waitListLock = threading.Lock()

alive = True;

taskQueue = Queue.Queue()
# Lists
# List of all running threads
threads = []

def threadExists(self,pIP):
"""Checks if there is already a thread with the given Name"""
for x in self.threads:
if x.name == pIP:
return x
return None

def threadTerminated(self,pThread):
"""Called when a Processing Thread terminates"""
with self.threadListLock:
self.threads.remove(pThread)
print "Thread removed"

def threadRegistered(self,pThread):
"""Registers a new Thread"""
self.threads.append(pThread)

def killThread(self):
self.alive = False

def run(self):
while(self.alive):
# print "Verarbeite Nachricht ", self.Message
# print "Von ", self.IP
try:
data, addtemp = self.taskQueue.get(True, 1)
addr, _junk = addtemp
with self.threadListLock:
foundThread=self.threadExists(str(addr))
# print "Thread " + self.name + " verarbeitet " + data
if (foundThread!=None):
#print "recycling thread"
foundThread.addTask(str(data))
else:
print "running new Thread"
t = pyProcThread.Thread(self)
t.name = str(addr)
t.addTask(str(data))
t.start()
self.threadRegistered(t)
self.taskQueue.task_done()
except Queue.Empty:
pass
print self.name, "terminating..."
with self.threadListLock:
for thread in self.threads:
thread.addTask(thread)

完整的输出,包括所有调试输出:

running new Thread
Konstruktor ausgefuehrt
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, initial)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
Exception in thread 192.168.1.102:
Traceback (most recent call last):
File "/opt/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/volume1/home/Max/Python/MyThread/pyProcThread.py", line 37, in run
print self.loc.father
AttributeError: 'thread._local' object has no attribute 'father'

<Thread(192.168.1.102, started 1106023568)>
<Queue.Queue instance at 0x40662b48>
<Thread(192.168.1.102, stopped 1106023568)>
Exception in thread pyAlloc-0:
Traceback (most recent call last):
File "/opt/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/volume1/home/Max/Python/MyThread/pyAllocThread.py", line 60, in run
foundThread.addTask(str(data))
File "/volume1/home/Max/Python/MyThread/pyProcThread.py", line 58, in addTask
print self.loc.todo
AttributeError: 'thread._local' object has no attribute 'todo'

Terminating main
192.168.1.102
DEINEMUDDA sent to 192.168.1.102 : 8082
pyAlloc-1 terminating...
<Thread(192.168.1.102, stopped 1106023568)>
<Queue.Queue instance at 0x40662b48>

正如您在日志中看到的,虽然它从未到达处理线程的主要函数中的print "processing,但在一段时间内似乎一切正常。

我已经在网络和 StackOverflow 上搜索过类似问题,但没有找到任何问题。预先感谢您提供的任何帮助,请原谅我的编码风格,我现在只编写了几天 Python,并且仍在学习它的一些功能。

编辑:当然,这个服务器的功能远不止于此。有一个主线程正在接收数据包并将它们发送到分配线程,以及后台的一堆其他东西。此外,服务器还远未完成,但我希望在开始其他事情之前让接收工作正常进行。

最佳答案

threading.local 是表示线程本地数据的类。线程本地数据是其值是特定于线程的数据,因此仅可用于本地 线程(创建local() 对象的线程)。换句话说,只有设置该值的线程才能看到该值。

因为您在处理线程的 __init__ 方法中设置了 loc.parent 值,但在分配器线程内执行,处理线程的线程局部变量将仅可用在分配器线程中。所以它不会在处理线程的 run() 中工作,因为它将由不同的线程(而不是分配器)执行。

关于Python: 'thread._local object has no attribute ' 待办事项',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9446702/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com