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