0
votes

I am creating a C program with threads that uses the SDL2 library on linux. The goal is to have a program that shows a blank window and prints "Hello, world!" to the console every 0.5 seconds.

So far the window is created successfully and the input and event handling works. The problem is that the "Hello, world!" message is only printed once, not every 0.5 seconds.

Here is the code:

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_thread.h>

static int thread_function(void *ptr)
{
    printf("Hello, world!\n");
    SDL_Delay(500);
    return 0;
}

void input(int *quit)
{
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            *quit = 1;
        }
    }
}

void render(SDL_Renderer *renderer)
{
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
}

int main(int argc, char *argv[])
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        printf("Could not initialize SDL2! %s\n", SDL_GetError());
        return 1;
    }

    SDL_Window *window = SDL_CreateWindow(
        "Program",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        400, 400, 0);
    if (window == NULL) {
        printf("Could not create window! %s\n", SDL_GetError());
        return 1;
    }

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    if (renderer == NULL) {
        printf("Could not create renderer! %s\n", SDL_GetError());
        return 1;
    }

    SDL_Thread *thread = SDL_CreateThread(thread_function, "thread", (void *)NULL);
    if (thread == NULL) {
        printf("Could not create thread! %s\n", SDL_GetError());
        return 1;
    }

    int quit = 0;
    while (quit != 1) {
        input(&quit);
        render(renderer);
    }

    SDL_WaitThread(thread, NULL);
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();

    return 0;
}

I compile the program with the following command:

gcc -lSDL2 main.c

The program compiles just fine, but the behavior is not what I expect and want. I expect the thread function to execute continuously in parallel with my main loop. But it seems that the thread function is only called once.

I have tried putting an infinite loop in the thread function, but this hogs the program. By this I mean that the event handler (input function) is no longer responsive and the program eventually crashes.

I am compiling this code on debian 10.3 with the package libsdl2-dev installed.

Am I completely missing the point in how to use threads or something else going wrong?

1

1 Answers

0
votes

Your code spawns thread that runs your function once and exits. It will not repeat.

If your thread have no exit condition (e.g. infinite loop) then after your main loop is broken by quit event - you block on SDL_WaitThread because thread never finishes. You need exit condition there too - e.g. making quit global variable and spinning thread loop on the same quit condition as main loop (there are other ways like signalling with semaphores, but basic idea remains the same).

However, spawning multiple threads that only occasionally do some work (not touching thread syncronisation here - that is a separate topic) and sleep most of the time is probably not the best idea of using system resources. SDL provides you with timers, which will be repeated at specified interval.