Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    How to exit a thread

    Scheduled Pinned Locked Moved WiPy 2&3
    8 Posts 3 Posters 3.0k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M Offline
      mohpor
      last edited by

      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?

      A 1 Reply Last reply Reply Quote 0
      • A Offline
        abilio @mohpor
        last edited by

        @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.

        1 Reply Last reply Reply Quote 0
        • robert-hhR Offline
          robert-hh
          last edited by

          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
          
          A 1 Reply Last reply Reply Quote 0
          • A Offline
            abilio @robert-hh
            last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • M Offline
              mohpor
              last edited by

              @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.

              1 Reply Last reply Reply Quote 0
              • robert-hhR Offline
                robert-hh
                last edited by

                @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.

                1 Reply Last reply Reply Quote 0
                • M Offline
                  mohpor
                  last edited by

                  @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.

                  1 Reply Last reply Reply Quote 0
                  • M Offline
                    mohpor
                    last edited by

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

                    1 Reply Last reply Reply Quote 0

                    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                    With your input, this post could be even better 💗

                    Register Login
                    • 1 / 1
                    • First post
                      Last post

                    Pycom on Twitter

                    Pycom