我如何暂停另一个线程(不是当前的线程)?

我正试图实现一个微控制器的模拟。 这种模拟并不是要做一个特定微控制器的时钟周期精确表示,而是检查代码的一般正确性。

我想有一个执行正常代码的“主线程”和执行ISR代码的第二个线程。 无论何时需要运行ISR,ISR线程都会挂起“主线程”。

当然,我想有一个function来阻止中断。 我想通过一个互斥体来解决这个问题,即只要ISR线程执行ISR代码,只要“中断被阻塞”,主线程就持有它。

一个POR(上电复位)可以通过不仅暂停而且杀死主线程(并启动一个执行PORfunction的新线程)来实现。

Windows API提供了必要的function。 但是,使用posix线程(在linux上)似乎不可能做到这一点。

我不想改变实际的硬件独立的微控制器代码。 所以插入任何东西来检查挂起的中断不是一个选项。

接收不良行为点的中断是可取的,因为这也发生在微控制器上(除非你阻止中断)。

有没有办法暂停在Linux上的另一个线程? (我想,debugging器必须以某种方式使用该选项。)

请不要告诉我这是个坏主意。 我知道在大多数情况下都是如此。 但主代码不使用标准库或锁/互斥/信号量。

Solutions Collecting From Web of "我如何暂停另一个线程(不是当前的线程)?"

不知何故,我认为发送其他线程SIGSTOP的作品。

但是,写一些涉及到senaogires.mutexes和全局变量的线程通信会更好。

你看,如果你暂停malloc()中的另一个线程,并调用malloc() – >死锁。

我有没有提到大量的C标准库函数,更let论你使用的其他库,将背后调用malloc()?

编辑:

嗯,没有标准的库代码。 也许使用信号处理程序中的setjmp / longjump()来模拟POR和一个信号处理器来模拟中断。

对那些持不同意见的人来说:EDIT之后的内容被接受了,这是一个不能用于其他场景的特定场景。

SIGSTOP不起作用 – 它总是停止整个过程。 相反,你可以使用一些其他的信号,比如SIGUSR1暂停和SIGUSR2恢复:

 // at process start call init_pthread_suspending to install the handlers // to suspend a thread use pthread_kill(thread_id, SUSPEND_SIG) // to resume a thread use pthread_kill(thread_id, RESUME_SIG) #include <signal.h> #define RESUME_SIG SIGUSR2 #define SUSPEND_SIG SIGUSR1 static sigset_t wait_mask; static __thread int suspended; // per-thread flag void resume_handler(int sig) { suspended = 0; } void suspend_handler(int sig) { if (suspended) return; suspended = 1; do sigsuspend(&wait_mask); while (suspended); } void init_pthread_suspending() { struct sigaction sa; sigfillset(&wait_mask); sigdelset(&wait_mask, SUSPEND_SIG) sigdelset(&wait_mask, RESUME_SIG); sigfillset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = resume_handler; sigaction(RESUME_SIG, &sa, NULL); sa.sa_handler = suspend_handler; sigaction(SUSPEND_SIG, &sa, NULL); } 

我非常恼火的答复如“你不应该暂停另一个线程,这是不好的”。 你为什么认为别人是白痴,不知道自己在做什么? 想象一下,其他人也听说过死锁,并且仍然意识到,要暂停其他线程。 如果你对他们的问题没有真正的答案,你为什么浪费你和读者的时间。

是的,国际海事组织的pthreads是非常短视的api,POSIX的耻辱。

Hotspot JAVA VM使用SIGUSR2来实现Linux上的JAVA线程挂起/恢复。

基于SIGUSR2的信号处理程序的过程可能是:

为SIGUSR2提供一个信号处理程序允许一个线程请求一个锁(它已经被信号发送线程获取)。

这暂停线程。

只要暂停线程释放锁,信号处理程序就可以(并将?)获取锁。 信号处理程序立即释放锁定并离开信号处理程序。

这恢复线程。

在开始实际处理ISR之前,可能需要引入一个控制变量来确保主线程在信号处理程序中。 (细节取决于信号处理程序是同步调用还是异步调用。)

我不知道,如果这在Java VM中完全是这样做的,但是我认为上述过程就是我所需要的。

Solaris有thr_suspend(3C)调用,可以做你想做的事情。 切换到Solaris的可能性?

除此之外,你可能将不得不做一些与互斥和/或信号量的体操。 问题是,当你检查互斥锁时,你将只会暂停,这可能是一个良好的表现。 根据你实际想要完成的事情,现在可能是可取的了。

让主线程执行ISR更有意义 – 因为这就是真实控制器的工作原理(据推测)。 只要在每个仿真指令之后检查是否有一个中断挂起,并且当前中断被启用 – 如果是的话,仿真一个到ISR的调用。

第二个线程仍然被使用 – 但它只是侦听引起中断的条件,并将相关中断标记为挂起(对于其他线程稍后提取)。

使用pthread_kill(3)和SIGUSR1,SIGUSER2信号的解决方案是一个很好的解决方案,但仍然可能导致并发问题。 有没有办法挂起所有线程(主线程除外)在一个安全的地方,即挂起时线程不应该获得任何锁定或不在系统调用中运行?