我正在尝试了解上下文切换的工作原理以及如何在接收到特定信号后使您的进程切换上下文。这是我的代码
#include<stdio.h>
#include<stdlib.h>
#include<ucontext.h>
#include<signal.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#define STACK_SIZE 4096
static ucontext_t thread1, thread2;
void thread1_fun() {
static int a = 1;
while (1) {
printf("calling thread1 for %d time\n", a);
sleep(5);
a > 20 ? a = 0 : a++;
}
}
void thread2_fun() {
static int a = 1;
while (1) {
printf("calling thread2 for %d time\n", a);
sleep(5);
a > 20 ? a = 0 : a++;
}
}
void sig_handler(int signal) {
static int curr_thread = 0;
printf("received signal %d\n", signal);
if (curr_thread == 1) {
curr_thread = 0;
printf("switching from thread1 to thread2\n");
setcontext(&thread1);
} else {
curr_thread = 1;
printf("switching from thread2 to thread1\n");
setcontext(&thread2);
}
}
int main() {
int i = 0;
struct sigaction act;
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, NULL);
/* sigaction(SIGTERM, &act, NULL); */
getcontext(&thread1);
thread1.uc_stack.ss_sp = malloc (STACK_SIZE);
thread1.uc_stack.ss_size = STACK_SIZE;
thread1.uc_stack.ss_flags = 0;
makecontext(&thread1, thread1_fun, 0);
getcontext(&thread2);
thread2.uc_stack.ss_sp = malloc (STACK_SIZE);
thread2.uc_stack.ss_size = STACK_SIZE;
thread2.uc_stack.ss_flags = 0;
makecontext(&thread2, thread2_fun, 0);
printf("%d\n", getpid());
while (1);
}
现在我从终端发出命令'kill -s SIGUSR1'。该进程在收到此信号后切换上下文,但问题是它两次打印“调用线程为 %d 时间” 。
例如,如果线程 1 打印“第三次调用线程1 ”并进入睡眠状态,如果我发送信号切换上下文,线程 1 正在睡眠,线程 2 开始执行,现在如果我再次发送信号切换上下文,那么线程 1 再次打印“调用线程 1第三次”。理想情况下,它应该从睡眠中醒来并增加 a 的值,对吗?为什么两次打印相同的值?
这是代码打印的输出:
接收信号 10
从线程2切换到线程1
调用thread2 1次
接收信号 10
从线程1切换到线程2
调用thread1 1次
接收信号 10
从线程2切换到线程1
调用thread2 1次
接收信号 10
从线程1切换到线程2
调用thread1 1次
请帮我解决一下这个。