如何安排两个任务?

Ras*_*yak 8 c windows embedded operating-system scheduled-tasks

我是流程/任务管理的新手.我想安排两个任务.假设,

fun1()  
{  
    printf("It will be printed in every 1 min \n");  
}  
fun2()  
{  
    printf("It will be printed in every 2 min \n");  
}  
main()  
{  
    fun1();  
    fun2();  
}
Run Code Online (Sandbox Code Playgroud)

那么如何安排它们,以便我得到我想要的输出.

我希望它在Code :: Blocks(Windows)中运行.我想fun1运行1分钟,fun2运行每2分钟一次.如果我可以在两个单独的过程中完成它,那么告诉我我该怎么做.我是否需要使用信号量,互斥量和所有?

cha*_*ite 15

编辑:这是上升的,所以我想为后代添加一个澄清.这不是解决这个问题的好方法 - 你永远不会想要手工完成这个.合作用户线程很好,可以用来实现协程等聪明的东西,但是如果你想这样做,你应该使用像libcoroutine这样的库来处理毛茸茸的东西.然而,虽然这不是一个实用的解决方案,但它仍然提出了一个有趣的想法,并且是一个有趣的调度示例和纯C99的局限性.

这是一个糟糕的答案.但是,它与平台无关,而且仅使用C99标准中定义的功能.

另一方面,它占用CPU(sleepC99 中没有功能,所以我们必须忙等待),使用我只能调用魔法来保留堆栈空间,并完全滥用setjmp.它甚至使用全局变量!然而,它的确有效.

该技术被称为合作用户线程,也称为光纤.正如我所提到的,我实现了它,使用setjmplongjmp.在context_switch做简单的轮循调度.

这是代码:

#include <stdio.h>
#include <setjmp.h>
#include <time.h>

static jmp_buf jmp[2];
static int cur;

void context_switch()
{
    /* sleep(1) */ /* C99 doesn't have any sleeping functions */
    if (!setjmp(jmp[cur])) {
        if ((sizeof(jmp)/sizeof(*jmp)) == ++cur)
            cur = 0;
        longjmp(jmp[cur], 1);
    }
}

void fun2()
{
    char cushion[1000]; /* reserve some stack space */
    time_t old_time, new_time;
    cushion[0] = '@'; /* don't optimize my cushion away */
    old_time = time(NULL);
        cur = 1; /* the first thread to context switch is this one */
    setjmp(jmp[1]);
    while (1) {
        context_switch();
        new_time = time(NULL);
        if ((new_time - old_time) > (2 * 60)) {
            old_time = new_time;
            printf("Printed every 2 minutes\n");
        }
    }
}

void fun1()
{
    char cushion[1000]; /* reserve some stack space */
    time_t old_time, new_time;
    cushion[0] = '@'; /* don't optimize my cushion away */
    if (!setjmp(jmp[0]))
        fun2();
    old_time = time(NULL);
    while (1) {
        context_switch();
        new_time = time(NULL);
        if ((new_time - old_time) > (1 * 60)) {
            old_time = new_time;
            printf("Printed every 1 minute\n");
        }
    }
}

int main(int argc, char **argv)
{
    fun1();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出:

$ gcc -ggdb -std=c99 -o silly silly_setjmp.c 
$ ./silly
Printed every 1 minute
Printed every 2 minutes
Printed every 1 minute
Printed every 1 minute
...
Run Code Online (Sandbox Code Playgroud)


Cli*_*ord 3

您的示例很简单,可以在不求助于任何操作系统提供的调度甚至操作系统计时服务的情况下进行调度,但是通常(对于重要的要求)在 Windows 中,您将使用多线程并允许操作系统执行调度。 main()已经是一个线程了,所以你只需要再创建一个。最简单的形式:

#include <stdio.h>
#include <windows.h>

DWORD WINAPI OneMinthread( LPVOID lpParam ) 
{  
    for(;;)
    {
        printf("It will be printed in every 1 min \n");  
        Sleep(60000) ;
    }
}  

int main()  
{  
    CreateThread( NULL, 0, OneMinthread, 0, 0, 0) ;
    for(;;)
    {
        printf("It will be printed in every 2 min \n");  
        Sleep(120000) ;
    }
}  
Run Code Online (Sandbox Code Playgroud)

有关 Win32 中线程的更完整处理,请参阅创建线程。请注意,.Net 框架还提供了一个更简单的基于类的线程接口。