Ask Your Question
0

How to stop code after a given time

asked 2024-04-09 19:13:42 +0100

ARG gravatar image

updated 2024-04-10 10:40:18 +0100

My question is the following: sometimes a computation runs too long, and I would rather for it to stop automatically, and move on to the next computation (in the best possible world keep a list of the cases that were skipped).

So I wanted to implement the solution to this (essentially) identical question:

https://stackoverflow.com/questions/1...

However in my case the function "foo" uses some functionalities of GAP. This apparently causes a crash:

** Gap crashed or quit executing '__SAGE_LAST__:="__SAGE_LAST__";;AllSmallGroups(\$sage1);;' **
Restarting Gap and trying again

The crash happens immediately on the first call of the GAP function. Is there any way to avoid this?

EDIT

The suggestion with alarm did not work for me (maybe it has to with my implementation). Basically the first interruption works correctly (after 20 seconds), then follows five minutes where nothing happens, after these five minutes the second iteration of the for loop begins, this second iteration is

from cysignals.alarm import alarm, AlarmInterrupt, cancel_alarm

for i in range(0,10):
    try:
        alarm(20)    
        print("Began computation at", time.localtime())
        foo(i)
    except AlarmInterrupt:      
        print("Timed out with ", i, "at", time.localtime())
        cancel_alarm()  ## the presence or absence of this line does not change anything
    else:
        print("Completed with", i, "at", time.localtime())
        cancel_alarm()

edit retag flag offensive close merge delete

Comments

1

I think there was something like alarm and AlarmInterrupt. Maybe you can use them with try and except.

tolga gravatar imagetolga ( 2024-04-09 20:41:16 +0100 )edit

@tolga thanks for the suggestion, but this used to cause strange dumps which eventually led to kernel death and stops the further computations. This basically misses the whole point (because I want the computation on other cases to go on, and not the kernel to die before it at least tried the other cases. Basically Alarm does not stop properly the computations... or at least it used to.

ARG gravatar imageARG ( 2024-04-10 07:42:43 +0100 )edit

@tolga I tried it and it doesn't work. After the first alarm() all further alarms are ignored. Also the kernel died after I did the KeyboardInterrupt (but that could be unrelated). Perhaps I misused the alarm code, so I edited it into the question...

ARG gravatar imageARG ( 2024-04-10 10:03:49 +0100 )edit
1
Max Alekseyev gravatar imageMax Alekseyev ( 2024-04-10 13:14:47 +0100 )edit

As for alarm, it needs to be reset after each use by calling alarm() without argumentsalarm(0), which will make it available for using again.

Max Alekseyev gravatar imageMax Alekseyev ( 2024-04-10 15:47:34 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2024-04-14 18:26:47 +0100

Max Alekseyev gravatar image

updated 2024-04-15 15:07:05 +0100

Here is a working example using function signal.alarm():

import time
from signal import alarm

def foo(i):
    sleep([1,1000][i%2])
    return True

for i in range(0,10):
    alarm(5)    
    print("Began computation at", time.localtime())
    try:
        foo(i)
    except KeyboardInterrupt:      
        print("Timed out with ", i, "at", time.localtime())
    else:
        print("Completed with", i, "at", time.localtime())
    alarm(0)   # reset

Try it at Sagecell.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2024-04-09 19:13:42 +0100

Seen: 365 times

Last updated: Apr 15