0

Hi I have C Program that starts multiple threads inside the main.cpp and then joins them at the end. Inside the thread functions there are mostly while loops for communication / data transfer (profinet and TCP) I have cleanup handler functions that are called when closing a thread.

I want to use <signal.h> to catch Ctrl+C and exit my program. The only solution that I can think of is doing this in every single thread function.

But is there a smarter way of doing this wihtout the need to catch Ctrl+C in every single thread function that exists? How can I ensure that every cleanup function is called in all threads? When Ctrl+C is catched?

If I use a static volatile sig_atomic_t variable for my while loops inside my void functions that I use for threads and set this variable to 0 with my signal handler function every thread is terminated correctly but it seems that it keeps stuck in the main.cpp loop that looks roughly like this:

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>

static volatile sig_atomic_t keep_running = 1;

static void sig_handler(int _)
{
    (void)_;
    keep_running = 0;
}

int main(void)
{
    char keystr[2], key;

    struct sigaction act;
    act.sa_handler = sig_handler;
    sigaction(SIGINT, &act, NULL);

    //all threads are created here

    while (keep_running) {
        printf("Press key + <enter>: ");
        scanf("%s", keystr);
        printf("\n");
        key = keystr[0];
        switch (key) { 
          //some cases and default here
          }
    }

    pthread_join(comm_process_thread, NULL);
    pthread_join(tcp_thread, NULL);
    pthread_join(cifx_thread, NULL);
    return EXIT_SUCCESS;
}
shyney
  • 67
  • 11
  • Please check this post https://stackoverflow.com/questions/4217037/catch-ctrl-c-in-c – Alan M May 02 '22 at 10:48
  • What platform are you on? – Paul Sanders May 02 '22 at 10:59
  • @AlanM this is not the answer to my question. I know how to catch ctrl +c. – shyney May 02 '22 at 12:11
  • @PaulSanders linux – shyney May 02 '22 at 12:12
  • 1
    Simpliest way of doing that is to have a global variable acting as a flag. If 'ctrl +c' is catched, then you set the flag to a determined value. After that, every relevent place in your code should test this flag and act accordingly. – Tom's May 02 '22 at 13:07
  • ... And if you do it that way, you won't fall foul of [this](https://man7.org/linux/man-pages/man7/signal-safety.7.html). – Paul Sanders May 02 '22 at 13:25
  • @PaulSanders I found the problem why it sometimes gets stuck in the while loop inside the main.cpp although all other threads were closed correctly. I have a scanf inside the while loop and sometimes it doesnt register ctrl+c as input and keeps stuck at the scanf call. is there a way to solve this problem? – shyney May 03 '22 at 08:30
  • @shyney The likely cause of this is that `scanf` is looping internally until it gets what it wants, so when it gets a signal it effectively ignores it. `scanf` is not my favourite function, you might do better to roll your own solution to parse the (expected) input here. – Paul Sanders May 03 '22 at 08:32

0 Answers0