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

时间:2015-07-16 17:49:01

标签: c multithreading signals interrupt

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

例如,我们有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做这件事。

2 个答案:

答案 0 :(得分:2)

我只能提供Linux方面的建议,但正如你所说的那样,感兴趣...

... raise执行以下操作(来自手册页):

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

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

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

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

答案 1 :(得分:1)

唯一能够中断线程的是本身或任务调度程序。 如果你要阻止其他人,你需要直接访问计时器硬件。

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

了解Windows在&#34;事件驱动的UI&#34;中向程序发送消息的功能。 使用一些整数为应用程序提供MSG结构,如消息代码,WPARAM和LPARAM。

定义您自己的结构并使用它向每个线程发送消息(某种形式的进程间通信)。并且,重要的是,将计时器设置为回调函数,或者与Sleep(50)(或更多)保持同步,以免“保持&#34;困扰&#34;你的处理器什么都没有。

希望这有助于对不起的英语抱歉。