[英]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.