簡體   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