【发布时间】:2017-01-19 03:07:30
【问题描述】:
我正在尝试了解上下文切换的工作原理以及如何在接收到特定信号后使您的进程切换上下文。这是我的代码
#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”。进程在收到此信号后切换上下文,但问题是它打印了 'calling thread for %d time' 两次。
例如,如果 thread1 打印“calling thread1 for 3rd time”并进入睡眠状态,而当我发送信号切换上下文时 thread1 处于睡眠状态,则 thread2 开始执行,现在如果我再次发送信号来切换上下文,那么 thread1 再次打印 'calling thread1 for 3rd time'。理想情况下,它应该从睡眠中醒来并增加 a 的值,对吗?为什么要打印两次相同的值?
这是代码打印的输出:
收到信号 10
从线程2切换到线程1
调用thread2 1次
收到信号 10
从线程1切换到线程2
调用thread1 1次
收到信号 10
从线程2切换到线程1
调用thread2 1次
收到信号 10
从线程1切换到线程2
调用thread1 1次
请帮帮我。
【问题讨论】:
标签: c linux multithreading signals ucontext