C任务切换的信号计时器



我正在构建一个简单的任务切换器,它在一个循环中运行两个函数。这个想法是,它运行f1一段时间,然后在一个无休止的循环中控制相同数量的f2,然后是f1,f2。

问题是,每当我运行程序时,第一次切换都很顺利,但下面的切换永远不会发生。陷入f2。

我尝试过最多归档3个开关的其他实现(之后程序被冻结)。

这是我目前的实现方式:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
int count = 0;
int flag  = 0;
void f1() {
for (;;) printf("A");
}
void f2() {
for (;;) printf("B");
}
void sched() {
flag = !flag;
if (flag)
f1();
else
f2();
}
void sighandler(int signo)
{
printf("signal %d occurred %d timesn",signo, ++count);
sched();
}
int main(void)
{
struct itimerval it;
struct sigaction act, oact;
act.sa_handler = sighandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGPROF, &act, &oact); 
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 10000;
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 10000;
setitimer(ITIMER_PROF, &it, NULL);
sched();
}

任何建议都将不胜感激。

您的信号处理程序调用sched(),它永远不会返回(但最终会出现在for (;;)的任何一个循环中)。因此,在第一次切换之后,您总是在信号处理程序内部,并且进一步的信号被屏蔽。

尽管你已经得到了很好的答案

您的信号处理程序调用sched(),它从不返回(但最终以for(;;)。。。

多任务实现的问题是,要使任务切换器工作,需要进行上下文切换。上下文切换器是一个例程,它在完成了到其他进程的所有上下文切换之后才返回,并且要调度的下一个任务是要返回的任务。这是的呼叫之王

yield();

但实际的上下文切换出现在yield的内部。上下文切换是不能作为简单例程(您调用并返回的某段代码)实现的东西,因为它必须在另一个上下文中返回。为此,您需要调用yield(),yield的代码必须将所有cpu寄存器更改为它们在其他上下文中的值(包括堆栈指针,因此这将使您需要两个堆栈),然后继续执行该代码(这将使程序在其他上下文返回)

因此,您需要有一些地方来存储所有任务的上下文,这些任务将允许并行运行。这包括任务的cpu状态和堆栈。然后,您需要一个例程(这是实际上下文切换的方式),将旧上下文(cpu正在使用的上下文)存储在保存存储中,并调用(并安装)要调度的新任务的上下文。类似于:

void task_switch(struct context *old_ctx, struct context *new_ctx);

并且这个例程必须用汇编程序编写。。。。因为它必须进行上下文切换,其中包括切换每个任务的堆栈。

你现在怎么看?

最新更新