Многопоточность Python - утечка памяти при использовании общего объекта (так)
У меня есть программы на Python, которые получают утечки памяти при использовании стороннего SO. Я упрощаю свой код следующим образом:
import time
import sys
import threading
import codecs
import ctypes
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
class TestThirdPartySo(object):
def __init__(self):
# this so uses thread-specific data
self.call_stat_so = ctypes.CDLL("./third_party_fun.so")
self.handle = self.call_stat_so._handle
def test_fun(self):
self.call_stat_so.fun_xxx()
def thread_fun():
TestThirdPartySo().test_fun()
def test_main(num):
count = 0
while True:
# create 3 * num threads
thread_num = 3
thread_list = []
for _ in range(thread_num):
thread_list.append(threading.Thread(target=thread_fun))
for thread in thread_list:
thread.start()
for thread in thread_list:
thread.join()
count += thread_num
time.sleep(0.01)
if count % 100 == 0:
print("finied %s" % count)
if count > num:
break
print("end !!!!")
if __name__ == '__main__':
num = sys.argv[1]
test_main(int(num))
Теперь я знаю, что этот общий объект использует данные, специфичные для потока. И я попытался закрыть SO после того, как назвал его следующим образом:
class TestThirdPartySo(object):
def __init__(self):
# this so uses thread-specific data
self.call_stat_so = ctypes.CDLL("./third_party_fun.so")
self.handle = self.call_stat_so._handle
def test_fun(self):
self.call_stat_so.fun_xxx()
def __del__(self):
dlclose_func(self.handle)
def dlclose_func(_handle):
dlclose_func_tmp = ctypes.cdll.LoadLibrary('libdl.so').dlclose
dlclose_func_tmp.argtypes = [ctypes.c_void_p]
dlclose_func_tmp(_handle)
Но я не смог закрыть так. И я также не уверен, что утечка памяти будет освобождена после закрытия файла so.
Если программа не использует многопоточность или создает фиксированное количество потоков (пул потоков), она работает нормально.
По какой-то причине мне нужно постоянно создавать потоки в моей программе. Что я могу сделать, чтобы предотвратить эту утечку памяти?