How to exit a thread



  • Hi,

    Noob question. What is the appropriate way of closing a thread? _thread provides a function called exit() but I'm not sure how it could be of use. There is no documentation on it.

    See this example:

    import _thread
    import time
    import gc
    
    gc.enable()
    
    def thr(delay,  id):
        print("id: %r, thr_id: %r" % (id,  _thread.get_ident()))
        _thread.exit()
    
    i = 0
    while True:
            time.sleep(1)
            print("Current thread is: %r" % (_thread.get_ident()))
            _thread.start_new_thread(thr, (0 ,  i))
            i += 1
        
    

    It will lead to a memory allocation error after 3 threads has been started, while ideally, it should never lead to a memory allocation error. How can I close a thread properly?



  • I can confirm this issue has been fixed in 1.2.2.b1. AMAZING! Kudos.



  • @robert-hh
    Thanks for the clarification, although I knew about collect() and I was doing it in another version which had no effect whatsoever, just posted a variation of my test case.

    I'm glad it is solved now and from what I got from posting in this forum, (fortunately for us) pycom doesn't need us to peer pressure on the issues, they actually read and act on every bug report, which is amazing!

    Cheers
    M.



  • @mohpor: Yes, I agree. I just wanted to confirm you observation. Sometimes it helps, if more people complain.
    With the new release of the firmware, the issue is gone. It is still advisable, to make a manual gc.collect(), otherwise the free memory will continuously go down, until eventually an automatic gc.collect is enforced. See log below, w/o that gc.collect() call in the loop.

    >>> import thread
    41392
    Current thread is: 1073547588
    id: 0, thr_id: 1073506400
    41232
    Current thread is: 1073547588
    id: 1, thr_id: 1073506400
    41072
    Current thread is: 1073547588
    id: 2, thr_id: 1073506400
    40912
    Current thread is: 1073547588
    id: 3, thr_id: 1073506768
    40752
    .....
    
    

    With a gc.collect() call in the loop, the free memory settles at a certain amount.



  • @robert-hh That's my original assessment. As you can see, each new Thread requires 8816 bytes and when the memory gets depleted, no more threads can be started.

    @abilio Thanks for the reply. If I could make a proper suggestion for the documentation, that would be the dire need of explaining memory management and most especially the implication of things like multi-threading have on memory. As I can see, there is very limited memory available on board which needs very careful management of it. I'm not even sure how I can use such limited memory in my application, but I hope when everything is done and ready, you'd optimize memory and we will have much more memory at hand.

    Cheers,
    M.



  • Hello @robert-hh, we were already working in a solution for problems like the one you detected. If everything goes well, is planned to be released this evening or tomorrow. As usual, thanks a lot for all the feedback you give.



  • Just for interest, I took the sample above and added gc.collect() and a print statement. The code now looks like:

    import _thread
    import time
    import gc
    
    def thr(delay,  id):
        print("id: %r, thr_id: %r" % (id,  _thread.get_ident()))
        _thread.exit()
    
    i = 0
    while True:
        time.sleep(1)
        gc.collect()
        print(gc.mem_free())
        print("Current thread is: %r" % (_thread.get_ident()))
        _thread.start_new_thread(thr, (0 ,  i))
        i += 1
    

    It fails at the 3rd attempt, getting now new buffer for the thread. It looks like the memory is not released, even when after 1 second the new started thread should have terminated and it's memory not needed any more. Out put below:

    MicroPython v1.8.6-299-gf7f29f4 on 2017-01-07; LoPy with ESP32
    Type "help()" for more information.
    >>> import thread
    25952
    Current thread is: 1073524960
    id: 0, thr_id: 1073497424
    17248
    Current thread is: 1073524960
    id: 1, thr_id: 1073505616
    8608
    Current thread is: 1073524960
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "thread.py", line 15, in <module>
    MemoryError: memory allocation failed, allocating 8192 bytes
    


  • @mohpor, when the method that handles the new thread finishes execution, the thread is automatically deleted, so the proper ay would be not calling anything at all.

    Thanks for the feedback on the lack of threading documentation. Threading is a relatively new feature in micropython, and there is still no documentation available. We will provide one in an upcoming release of the docs.


Log in to reply
 

Pycom on Twitter