1

SDL 2 has nice functions for creating and managing threads and is cross platform. SDL 1 had a function to kill those threads, but SDL 2 no longer has this as they mention on their wiki.

I used to program threading with the OS native functions (Windows threads and Linux pthread) where I was able to do this.

I know you should program your threads so that you should never have to kill them, and I am reasonably good at writing threads, but now I am working on a project that will allow users to write script code that I will run from within threads so they can run in parallel.

If these scripts run longer than say 10s, they are considered hanging. If a user wants to exit the application and the threads are busy, they will have to wait for these threads to finish, and in case of a bad script, that end may never come.

In that case, I think killing the thread is the only/best option, notifying the user that the script is bad.

Why does SDL 2 no longer support this and is there a way around it?

scippie
  • 2,011
  • 1
  • 26
  • 42
  • 2
    Killing threads forcibly is generally not good, as it will kill the thread without letting it clean up after itself. Instead use a flag (like an atomic boolean variable) that is checked by the thread at regular intervals, and if set the thread will exit. Some systems also have the concept of thread *interuptions* which can be used to ask a thread to end. – Some programmer dude Jul 26 '19 at 11:04
  • On which OS are you? Linux? – user803422 Jul 26 '19 at 11:56
  • 2
    It was removed because some systems don't offer that functionality, and it is unsafe to use even on ones that does. Your user threads can easily corrupt your memory so it can't be a safety measure. What will happen if thread holds a mutex (or worse, spinlock) and you kill it? That being said, you can get thread id via `SDL_GetThreadID` and then use it for e.g. `pthread_kill`. – keltar Jul 26 '19 at 12:57
  • @Someprogrammerdude: I know all about that and you are completely correct but that is not the point. I want to make the software quittable in case of a bad user script without having them using the task manager. As soon as the process itself exits, the OS will clean up the mess the killed threads made. It's not the kind of software that needs to run forever. – scippie Jul 26 '19 at 15:05
  • @user803422: I want to be as cross platform as possible, in the least Linux and Windows. I develop on Linux. I did threads myself before with windows API threads and Linux pthreads and the latter worked on Mac OS X too, but I hoped SDL would do that for me now. – scippie Jul 26 '19 at 15:06
  • @keltar: I will look into that. That way, I will only have to do the platform dependent stuff for the platforms I want to release to. Thanks for the useful answer! – scippie Jul 26 '19 at 15:07
  • @Someprogrammerdude: can you point me to API for thread interuptions on both Linux and Windows? – scippie Jul 26 '19 at 15:08
  • You can set e.g. signal handler and break thread on signal, or thread-specific timer on some platforms, but that's no better than OS kill, sounds potentially too unstable to be useful. If you can, put a workload into separate process and communicate via channel or shared memory (or fork, depending on what you do). That way you can safely kill it any time you want, and have some safety guarantees. I can't imagine killing a thread executing the code I have no control over and really expecting things not to collapse (may be even not instantly but far later, which is far worse). – keltar Jul 26 '19 at 18:03

1 Answers1

0

Of course, the first thought should be: is it really necessary. Can't you add signals that ask the thread to quit properly and clean up?

Threads should always have a mechanism of stopping on itself or watching for quit-requests.

But when your project has all that but offers users to write their own code for these threads, for example via a Lua script, you will always have people messing things up by adding an endless loop (probably not on purpose). Watching for events during idle time will not help in that case because there will be no idle time.

So in my opinion, it is a bad decision that SDL doesn't have a Thread kill function. It is the same as saying that cars shouldn't have airbags as users are expected to take precautions of not crashing into things. Meanwhile, lots of lives have been saved by drivers who crashed anyway even when told not to.

The best answer I have seen is by doing it yourself in a platform dependent way. SDL offers a way to get the Thread ID: SDL_GetThreadID. This ID is the same ID the OS gave the thread and can then be used to kill the thread with a platform specific function:

#ifdef _WIN32
TerminateThread(SDL_GetThreadID(t), 0);
#end
#ifdef __linux
pthread_kill(SDL_GetThreadID(t), 0);
#endif

I don't know about the other platforms supported by SDL, so you should make sure to research their way too of course. I guess SDL also uses the pthread implementation for Mac OS so it will probably work there too. It did when I wrote my own threading code in the past.

I am looking into the suggested thread interuptions. If that proves helpful, I will post it here too.

Another possible solution would of course be that the code that makes the external code possible can be asked to stop execution. I don't think Lua offers such a thing but if I find it, I will certainly prefer it.

Edit: For Lua, it is possible to set a debug hook that triggers every N instructions. This way, it should be possible to check on a quit-request while Lua is executing external code. I will certainly look into this (mainly to check on performance) so that killing the thread will certainly become the last resort. See lua_sethook.

scippie
  • 2,011
  • 1
  • 26
  • 42
  • Should be easier (and safe) to do from [lua side](https://stackoverflow.com/questions/11268857/how-to-enforce-lua-scripts-runtime-limit). – keltar Jul 26 '19 at 18:21