简体   繁体   中英

Signal handler getting called in wrong thread

I want to know if its possible to interrupt main thread and ask it to execute some callback. The main thread should continue with what it was doing after completing the callback.

For instance, we have 2 threads t1 and m1 (main thread). t1 will interrupt m1 (main thread) and ask it to call a function with some parameters. The m1 (main thread) will stop doing what it was doing before and will start executing the function. The after finishing the function, it will get back to what it was doing earlier.

I want to replicate what hardware interrupt does. I have one thread that reads data from a file. Then it should ask main thread to call a function. Main thread will be doing something. It should stop doing it and start executing the function. After completing it, main thread should continue with what it was doing

I have written following code using signals

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

static void catch_function(int signo) {
    int id = GetCurrentThreadId();
    printf("\nThread ID is %d",id);
    signal(SIGINT, catch_function);
}


DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 
{
    int id = GetCurrentThreadId();
    printf("\nChild Thread ID is %d",id);
    while(1)
    {
        Sleep(50);
        if (raise(SIGINT) != 0) {
            fputs("Error raising the signal.\n", stderr);
            return EXIT_FAILURE;
        }
    }
    return 0;
}


int main(void) {

    int id = GetCurrentThreadId();
    printf("\nMain Thread ID is %d",id);
    if (signal(SIGINT, catch_function) == SIG_ERR) {
        fputs("An error occurred while setting a signal handler.\n", stderr);
        return EXIT_FAILURE;
    }

    HANDLE thread;
    DWORD  threadId;
    thread = CreateThread(NULL, 0, &MyThreadFunction, NULL, 0, &threadId);
    if(!thread)
    {
        printf("CreateThread() failed");
    }

    while(1)
    {
        Sleep(50);
    }
    return 0;
}

The output of code is

Main Thread ID is 6124 
Child Thread ID is 7854
Thread ID is       7854
Thread ID is       7854

So my question is should not the signal handler be called in Main thread? I want main thread to call the handler function not the thread which raise the signal? please let me know what is the correct way of achieving this.

PS. I have to do it for both windows and linux.

I can only offer advice from a Linux side, but as you said that was of interest too then...

... raise does the following (from the manual page):

The  raise()  function sends a signal to the calling process or thread.

So in a multi-threaded program it is the thread that calls raise that will get the signal.

On Linux, for threading, you'll probably be using pthreads, in which case you have pthread_kill , this sends a specific signal to a specific thread. You'd need to use pthread_self in the main thread to get the thread id, then pass this to the worker thread. The worker thread can then send signals directly to the main thread.

I suspect you need to find something similar for Windows, but that's not something I know about.

The only one that can interrupt a thread is itself or the Task Scheduler. If you were to stop someone else you would need direct access to timer hardware.

You can do what Ed Heal said. Use conditional variables and semaphores. My advice is to build up a linked list or even just an array storing what to do and who is the one wich should do it.

See what Windows does to send messages to the program in "event-driven UI". A MSG struct is given to the application with some integers, like message code, WPARAM and LPARAM.

Define a structure of your own and use it to send messages to each thread (some form of interprocess communication). And, that's important, set a timer to a callback function or keep with your Sleep(50) (or more) to not keep "bothering" your processor for nothing.

Hope this helps and sorry for bad english.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM