信号处理程序获取调用在错误的线程 [英] Signal handler getting called in wrong thread

查看:185
本文介绍了信号处理程序获取调用在错误的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道,如果它可以中断主线程,并要求它来执行一些回调。主线程应继续与它完成回调后做什么。

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.

例如,我们有2个线程T1和M1(主线程)。 T1将中断M1(主线程),并要求它调用函数与一些参数。货币供应量M1(主线程)将停止做它之前做的和将开始执行的功能。在完成功能后,会回到以前它是做什么的。

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

我已经写了以下使用的信号code

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;
}

code的输出

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。我必须这样做,为Windows和Linux。

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

推荐答案

我只能从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.

在Linux中,线程,你可能会使用pthreads的,在这种情况下,你有 pthread_kill ,这发出了一个信号,具体到特定线程。你需要使用 pthread_self 在主线程获得线程ID,然后把它传递给工作线程。然后,工作线程可以直接发送信号到主线程。

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.

我怀疑你需要找到的Windows类似的东西,但是这不是我知道的。

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

这篇关于信号处理程序获取调用在错误的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆