在 Python 中维护一个可自动清理的线程列表
Maintain an auto-cleanable list of threads in Python
我维护了一个 threads
列表,我想 线程完成后自动从列表中删除线程 。
我找到了这个方法:
import threading, time
def f(seconds, info):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
threads.remove(info['thread'])
def newaction(seconds):
info = {}
thread = threading.Thread(target=f, args=(seconds, info))
info['thread'] = thread
thread.start()
threads.append(thread)
threads = []
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(threads)
有效:
starting 1
starting 2
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
finished 1
[<Thread(Thread-2, started 712)>]
[<Thread(Thread-2, started 712)>]
[<Thread(Thread-2, started 712)>]
finished 2
[]
[]
[]
[]
但是必须通过一个命令 info
的事实有点麻烦。我使用它是因为显然我不能在 args
...
中传递 thread
thread = threading.Thread(target=f, args=(seconds, thread))
# ^ not created yet!
...当 Thread
对象尚未创建时!
在 Python 中是否有更自然的方法来维护可自动清理的线程列表?
import threading
def get_status_of_threads():
current_threads = threading.enumerate()
thread_data = []
for item in current_threads:
try:
print(str(item.target))
except AttributeError:
print("item", str(item))
thread_data.append({"thread_name": item.getName(), "status": int(item.is_alive()), "id": item.ident})
return thread_data
上面的代码在Python2.7中测试过,如果你想持续监控线程,你可以在一个单独的线程中使用它,或者你可以将它暴露为一个API,所以您可以随时检查。这也将有助于减少资源浪费。
对于API,您可以使用json2html.convert({"thread_data":thread_data})
功能以表格形式更美观地显示它。
你有 current_thread()
功能。
import threading, time
def f(seconds):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
threads.remove(threading.current_thread())
def newaction(seconds):
thread = threading.Thread(target=f, args=(seconds,))
thread.start()
threads.append(thread)
threads = []
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(threads)
输出:
starting 1
starting 2
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
finished 1
[<Thread(Thread-2, started 4388)>]
[<Thread(Thread-2, started 4388)>]
[<Thread(Thread-2, started 4388)>]
finished 2
[]
[]
[]
[]
Thread 的子类化产生了一种具有自然语法和安全位置来保存线程列表的解决方案。您也不必在要在另一个线程中 运行 的每个函数的末尾包含删除线程的指令。只需使用子类。
import threading, time
class AutoRemovingThread(threading.Thread):
threads = []
def __init__(self, func, *args, **kwargs):
super().__init__()
self.threads.append(self)
self.func = func
self.args = args
self.kwargs = kwargs
def run(self):
self.func(*self.args, **self.kwargs)
self.threads.remove(self)
def f(seconds):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
def newaction(seconds):
AutoRemovingThread(f, seconds).start()
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(AutoRemovingThread.threads)
输出:
starting 1
starting 2
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
finished 1
[<AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-2, started 1072)>]
finished 2
[]
[]
[]
[]
python-3.8
我维护了一个 threads
列表,我想 线程完成后自动从列表中删除线程 。
我找到了这个方法:
import threading, time
def f(seconds, info):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
threads.remove(info['thread'])
def newaction(seconds):
info = {}
thread = threading.Thread(target=f, args=(seconds, info))
info['thread'] = thread
thread.start()
threads.append(thread)
threads = []
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(threads)
有效:
starting 1
starting 2
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
[<Thread(Thread-1, started 1612)>, <Thread(Thread-2, started 712)>]
finished 1
[<Thread(Thread-2, started 712)>]
[<Thread(Thread-2, started 712)>]
[<Thread(Thread-2, started 712)>]
finished 2
[]
[]
[]
[]
但是必须通过一个命令 info
的事实有点麻烦。我使用它是因为显然我不能在 args
...
thread
thread = threading.Thread(target=f, args=(seconds, thread))
# ^ not created yet!
...当 Thread
对象尚未创建时!
在 Python 中是否有更自然的方法来维护可自动清理的线程列表?
import threading
def get_status_of_threads():
current_threads = threading.enumerate()
thread_data = []
for item in current_threads:
try:
print(str(item.target))
except AttributeError:
print("item", str(item))
thread_data.append({"thread_name": item.getName(), "status": int(item.is_alive()), "id": item.ident})
return thread_data
上面的代码在Python2.7中测试过,如果你想持续监控线程,你可以在一个单独的线程中使用它,或者你可以将它暴露为一个API,所以您可以随时检查。这也将有助于减少资源浪费。
对于API,您可以使用json2html.convert({"thread_data":thread_data})
功能以表格形式更美观地显示它。
你有 current_thread()
功能。
import threading, time
def f(seconds):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
threads.remove(threading.current_thread())
def newaction(seconds):
thread = threading.Thread(target=f, args=(seconds,))
thread.start()
threads.append(thread)
threads = []
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(threads)
输出:
starting 1
starting 2
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
[<Thread(Thread-1, started 4588)>, <Thread(Thread-2, started 4388)>]
finished 1
[<Thread(Thread-2, started 4388)>]
[<Thread(Thread-2, started 4388)>]
[<Thread(Thread-2, started 4388)>]
finished 2
[]
[]
[]
[]
Thread 的子类化产生了一种具有自然语法和安全位置来保存线程列表的解决方案。您也不必在要在另一个线程中 运行 的每个函数的末尾包含删除线程的指令。只需使用子类。
import threading, time
class AutoRemovingThread(threading.Thread):
threads = []
def __init__(self, func, *args, **kwargs):
super().__init__()
self.threads.append(self)
self.func = func
self.args = args
self.kwargs = kwargs
def run(self):
self.func(*self.args, **self.kwargs)
self.threads.remove(self)
def f(seconds):
print('starting', seconds)
time.sleep(seconds)
print('finished', seconds)
def newaction(seconds):
AutoRemovingThread(f, seconds).start()
newaction(1)
newaction(2)
for _ in range(10):
time.sleep(0.3)
print(AutoRemovingThread.threads)
输出:
starting 1
starting 2
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-1, started 8436)>, <AutoRemovingThread(Thread-2, started 1072)>]
finished 1
[<AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-2, started 1072)>]
[<AutoRemovingThread(Thread-2, started 1072)>]
finished 2
[]
[]
[]
[]
python-3.8