繁体   English   中英

信号处理程序在错误的线程中被调用

[英]Signal handler getting called in wrong thread

我想知道是否有可能中断主线程并要求它执行一些回调。 完成回调后,主线程应继续执行其操作。

例如,我们有2个线程t1和m1(主线程)。 t1将中断m1(主线程)并要求其调用带有某些参数的函数。 m1(主线程)将停止执行之前的操作,并将开始执行该功能。 完成功能后,它将返回到之前的操作。

我想复制硬件中断的功能。 我有一个线程从文件中读取数据。 然后,它应要求主线程调用函数。 主线程将做某事。 它应该停止执行并开始执行该功能。 完成后,主线程应继续其所做的工作

我已经使用信号编写了以下代码

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

代码的输出是

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

所以我的问题是信号处理程序是否应该在主线程中调用? 我要主线程调用处理程序函数,而不是发出信号的线程? 请让我知道实现此目标的正确方法。

PS。 我必须为Windows和Linux都这样做。

我只能从Linux方面提供建议,但是正如您所说的那样,那时也很有趣...

... raise的确以下(从手册页):

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

因此,在多线程程序中,调用raise的线程将获得信号。

在Linux上,对于线程化,您可能会使用pthreads,在这种情况下,您将拥有pthread_kill ,这会将特定信号发送到特定线程。 您需要在主线程中使用pthread_self来获取线程ID,然后将其传递给工作线程。 然后,工作线程可以直接将信号发送到主线程。

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

唯一可以中断线程的线程本身就是任务调度程序。 如果要停止其他人,则需要直接访问计时器硬件。

您可以按照Ed Heal所说的做。 使用条件变量和信号量。 我的建议是建立一个链表,甚至只是一个数组,存储要做什么以及谁应该做。

查看Windows如何在“事件驱动的UI”中将消息发送到程序。 MSG结构使用一些整数(例如消息代码,WPARAM和LPARAM)提供给应用程序。

定义自己的结构并将其用于将消息发送到每个线程(某种形式的进程间通信)。 而且,重要的是,将计时器设置为回调函数,或者保持Sleep(50) (或更高),以免使处理器毫无负担。

希望这对您有所帮助,对不起英语不好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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