NordicSemiconductor / pynrfjprog

Python wrapper around the nrfjprog dynamic link library (DLL)
Other
74 stars 26 forks source link

MultiAPI leaks threads #10

Closed pengi closed 6 years ago

pengi commented 6 years ago

When using the MutliAPI, the close() doesn't clean up all threads.

Using the test code:

from pynrfjprog.MultiAPI import MultiAPI as API

import threading

for i in range(1000):
    print ""
    print "Iteration %d" % (i,)
    api = API('NRF52')
    api.open()
    api.close()
    api = None

    print "%d threads active" % (len(threading.enumerate()),)

Results in:


Iteration 0
2 threads active

Iteration 1
3 threads active

Iteration 2
4 threads active

Iteration 3
5 threads active

Iteration 4
6 threads active

Iteration 5
7 threads active

Iteration 6
8 threads active

Iteration 7
9 threads active

Iteration 8
10 threads active

Iteration 9
11 threads active

Iteration 10
12 threads active

Iteration 11
13 threads active

Iteration 12
14 threads active

Iteration 13
15 threads active

Iteration 14
16 threads active

Iteration 15
17 threads active

Iteration 16
18 threads active

Iteration 17
19 threads active

Iteration 18
20 threads active

Iteration 19
21 threads active

Iteration 20
22 threads active

Iteration 21
23 threads active

Iteration 22
24 threads active

Iteration 23
25 threads active

Iteration 24
26 threads active

Iteration 25
Traceback (most recent call last):
  File "testpynrfjprog.py", line 8, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pynrfjprog/MultiAPI.py", line 61, in __init__
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/__init__.py", line 218, in Queue
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/queues.py", line 68, in __init__
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/synchronize.py", line 147, in __init__
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/synchronize.py", line 75, in __init__
OSError: [Errno 24] Too many open files
Exception AttributeError: AttributeError() in <bound method MultiAPI.__del__ of <pynrfjprog.MultiAPI.MultiAPI object at 0x103c5f850>> ignored

threading.enumerate() returns an increasing list of instances like: <Thread(QueueFeederThread, started daemon 123145431425024)>

simtind commented 6 years ago

We are aware of the issue. Currently we rely on the Python garbage collector to pick up the threads, but it can take a long time before the object is cleaned. Upon garbage collection the threads are terminated.

We are looking into adding two new methods is_alive() and terminate() to the MultiAPI wrapper to allow the user to fix this in systems where this is a problem. The terminate function will also be called explicitly in exit, so the context handler does not require any extra handling.

simtind commented 6 years ago

MultiAPI.terminate() and MultiAPI.is_alive() is available in version 9.7.0.