Search code examples
cmultithreadingsdl

Killing SDL 2 threads (C)


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?


Solution

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