Page 1 of 1

How to interrupt an infinite loop executed by exec in a thread?

Posted: Tue Mar 09, 2021 6:07 am
by lgyer
Hi,

There are two problems.
One is how to terminate a thread in another thread by using _thread module?
Another problem is how to interrupt an infinite loop executed by exec in a thread? like this:

Code: Select all

import _thread
import time
def task1():
    print('task1 running')
    exec('while True:\n  print("task1 ~~")\n  time.sleep(1)',globals())
def task2():
   print("task2 running")
   while True:
      print("task2 !")
      time.sleep(1)
_thread.start_new_thread(task1,())
_thread.start_new_thread(task2,())
When I use Ctrl+E and Ctrl+D to run this code and use Ctrl+C to stop it, it can't be terminated.
Why can Not I stop it?

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Thu Mar 11, 2021 9:37 pm
by CmdrDeLiver
Perhaps a flag to indicate it is time to exit?

Code: Select all

import _thread
import time

f_run = True

def task1():
    print('task1 running')
    exec('while f_run:\n  print("task1 ~~")\n  time.sleep(1)',globals())
def task2():
   print("task2 running")
   while f_run:
      print("task2 !")
      time.sleep(1)
_thread.start_new_thread(task1,())
_thread.start_new_thread(task2,())
time.sleep(90)
f_run = False
You could also you an if f_run == False: break to escape at any line that suits you.

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Fri Mar 12, 2021 6:30 am
by lgyer
CmdrDeLiver wrote:
Thu Mar 11, 2021 9:37 pm
Perhaps a flag to indicate it is time to exit?

Code: Select all

import _thread
import time

f_run = True

def task1():
    print('task1 running')
    exec('while f_run:\n  print("task1 ~~")\n  time.sleep(1)',globals())
def task2():
   print("task2 running")
   while f_run:
      print("task2 !")
      time.sleep(1)
_thread.start_new_thread(task1,())
_thread.start_new_thread(task2,())
time.sleep(90)
f_run = False
You could also you an if f_run == False: break to escape at any line that suits you.
Hi CmdrDeLiver
Thanks for your reply.
Yes, it can work when the flag to be confirmed. But if the code was very long to execute, how to make it be interrupt immedicately? Is there any way?

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Fri Mar 12, 2021 2:11 pm
by CmdrDeLiver
Hey Igyer,

This is a job for break and continue! Break exits the loop immediately. Continue forces the loop back to the beginning where the loop condition is evaluated. Both can give you finite control over your exit point.

Code: Select all

while True:
  if f_run == False:
    break
  sleep(1)
  print("still running")
This might be helpful to understanding loop control: https://realpython.com/python-while-loop/

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Sat Mar 13, 2021 8:14 am
by lgyer
CmdrDeLiver wrote:
Fri Mar 12, 2021 2:11 pm
Hey Igyer,

This is a job for break and continue! Break exits the loop immediately. Continue forces the loop back to the beginning where the loop condition is evaluated. Both can give you finite control over your exit point.

Code: Select all

while True:
  if f_run == False:
    break
  sleep(1)
  print("still running")
This might be helpful to understanding loop control: https://realpython.com/python-while-loop/
Hi CmdrDeLiver,

Maybe I didn't descript my problem precisely. I know the break can make the loop stopped.
My problem is how to interrupt the loop as quick as possible ,like this:

Code: Select all

while True:
    if f_run == False:
    	break
    balabalabala.......   # these statements could handle some tasks which may consume time very long, maybe 5s - 10s..
    sleep(10)  # like this. So the extreme case is that the f_run has been True, but it still need wait for 10 seconds, instead of exiting immediately.

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Sat Mar 13, 2021 3:56 pm
by CmdrDeLiver
Have you looked at _thread.exit? I'm unsure how/if it is implemented in micropython as there is zero documentation on the wiki. You might want to go to the source and figure it out.
lgyer wrote:
Sat Mar 13, 2021 8:14 am
My problem is how to interrupt the loop as quick as possible ,like this:
CODE: SELECT ALL

while True:
if f_run == False:
break
balabalabala....... # these statements could handle some tasks which may consume time very long, maybe 5s - 10s..
sleep(10) # like this. So the extreme case is that the f_run has been True, but it still need wait for 10 seconds, instead of exiting immediately.
I see what you mean and there's a simple answer. You can put logic between each statement to break out. That might include turning the sleep statement into something along the lines of

Code: Select all

for i in range(100):
    if f_run == False:
    	break
    sleep(0.1)
Check out _thread.exit() though. It might have the secret sauce you're looking for.

Re: How to interrupt an infinite loop executed by exec in a thread?

Posted: Tue Mar 16, 2021 7:39 am
by lgyer
CmdrDeLiver wrote:
Sat Mar 13, 2021 3:56 pm
Have you looked at _thread.exit? I'm unsure how/if it is implemented in micropython as there is zero documentation on the wiki. You might want to go to the source and figure it out.
lgyer wrote:
Sat Mar 13, 2021 8:14 am
My problem is how to interrupt the loop as quick as possible ,like this:
CODE: SELECT ALL

while True:
if f_run == False:
break
balabalabala....... # these statements could handle some tasks which may consume time very long, maybe 5s - 10s..
sleep(10) # like this. So the extreme case is that the f_run has been True, but it still need wait for 10 seconds, instead of exiting immediately.
I see what you mean and there's a simple answer. You can put logic between each statement to break out. That might include turning the sleep statement into something along the lines of

Code: Select all

for i in range(100):
    if f_run == False:
    	break
    sleep(0.1)
Check out _thread.exit() though. It might have the secret sauce you're looking for.
Okay, thanks a lot. I'll try it. Thanks again.