Wer*_*thé 5 linux multithreading pthreads
我正在尝试实现微控制器的仿真.该仿真并不意味着对一个特定微控制器进行时钟周期精确表示,而是检查代码的一般正确性.
我想过有一个执行普通代码的"主线程"和一个执行ISR代码的第二个线程.每当需要运行ISR时,ISR线程就会挂起"主线程".
当然,我想要一个阻止中断的功能.我想用一个互斥体解决这个问题,ISR线程只要执行ISR代码就会保留,而主线程只要"中断被阻塞"就会保存它.
然后可以通过暂停但杀死主线程(以及启动执行POR功能的新线程)来实现POR(上电复位).
Windows API提供了必要的功能.但似乎不可能使用posix线程(在linux上)执行上述操作.
我不想改变实际的硬件独立微控制器代码.因此,插入任何内容以检查挂起的中断都不是一种选择.
在非性能良好的点接收中断是可取的,因为这也发生在微控制器上(除非阻止中断).
有没有办法在Linux上挂起另一个线程?(我认为,调试器必须以某种方式使用该选项.)
拜托,不要告诉我这是一个坏主意.我知道在大多数情况下都是如此.但主代码不使用标准库或锁/互斥量/信号量.
luc*_*cho 11
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);
}
Run Code Online (Sandbox Code Playgroud)
我很反感像"你不应该暂停另一个线程,那是坏事".伙计们为什么你认为别人是白痴,不知道他们在做什么?想象一下,其他人也听说过死锁,而且在完全意识中,他们还想暂停其他线程.如果你对他们的问题没有真正的答案,为什么要浪费你和读者的时间.
是的,IMO pthreads是非常短视的api,对POSIX来说是一种耻辱.
Hotspot JAVA VM使用SIGUSR2为Linux上的JAVA线程实现挂起/恢复.
基于SIGUSR2的信号处理程序的过程可能是:
为SIGUSR2提供信号处理程序允许线程请求锁定(已经由信号发送线程获取).
这会挂起线程.
一旦挂起线程释放锁定,信号处理程序就可以(并且将会)获得锁定.信号处理程序立即释放锁并离开信号处理程序.
这将恢复该线程.
在开始实际处理ISR之前,可能需要引入一个控制变量以确保主线程在信号处理程序中.(细节取决于是同步还是异步调用信号处理程序.)
我不知道,如果这正是它在Java VM中的完成方式,但我认为上述过程可以满足我的需要.
不知怎的,我认为发送另一个线程 SIGSTOP 是有效的。
但是,最好编写一些涉及 senaogires.mutexes 和全局变量的线程通信。
你看,如果你在 malloc() 中挂起另一个线程并且调用 malloc() -> 死锁。
我是否提到过,许多 C 标准库函数(更不用说您使用的其他库)都会在您背后调用 malloc() ?
编辑:
嗯,没有标准库代码。也许使用信号处理程序中的 setjmp/longjump() 来模拟 POR,并使用信号处理程序来模拟中断。
对于那些一直对此表示反对的人:编辑后的内容的答案被接受,这是一个特定的场景,不能在任何其他场景中使用。