简体   繁体   English

erlang如何通过一个OS线程实现抢占式调度?

[英]How does erlang implements preemptive scheduling with one OS thread?

I want to know how erlang's VM preempts the running code and contexts the stack. 我想知道erlang的VM如何抢占正在运行的代码并在堆栈中使用上下文。 How it can be done in a language such as c? 用c之类的语言怎么做?

The trick is that the Erlang runtime has control over the VM, so it can - entirely in userspace - keep track of how many VM instructions it's already executed (or, better yet, an estimate or representation of the actual physical computation required for those instructions - aka "reductions" in Erlang VM parlance) and - if that number exceeds some threshold - immediately swap around process pointers/structs/whatever and resume the execution loop. 诀窍在于,Erlang运行时可以控制VM,因此它可以-完全在用户空间中-跟踪已经执行了多少VM指令(或者更好的是,估算或表示这些指令所需的实际物理计算) -又称“减少”(在Erlang VM看来),并且-如果该数目超过某个阈值,则立即在进程指针/结构/任何内容之间交换并恢复执行循环。

Think of it something like this (in kind of a pseudo-C that may or may not actually be C, but I wouldn't know because I ain't a C programmer, but you asked how you'd go about it in C so I'll try my darndest): 考虑一下这样的事情(某种可能是或可能不是C的伪C,但我不知道是因为我不是C程序员,但是您问过如何在C中使用它所以我会尽力而为):

void proc_execute(Proc* proc)
{
    /* I don't recall if Erlang's VM supports different
       reduction limits for different processes, but if it
       did, it'd be a rather intuitive way to define process
       priorities, i.e. making sure higher-priority processes
       get more reductions to spend */
    int rds = proc->max_reductions;

    for (; rds > 0; rds--) {
        /* Different virtual instructions might execute different numbers of
           physical instructions, so vm_execute_next_instruction will return
           however many reductions are left after executing that virtual
           instruction. */
        rds = vm_execute_next_instruction(proc, rds);
        if (proc->exited) break;
    }
}

void vm_loop(Scheduler* sched)
{
    Proc *proc;

    for (;;) {
        proc = sched_next_in_queue(sched);
        /* we'll assume that the proc will be null if the
           scheduler doesn't have any processes left in its
           list */
        if (!proc) break;
        proc_execute(proc);
    }
}

Proc* sched_next_in_queue(Scheduler* sched)
{
    if (!sched->current_proc->exited) {
        /* If the process hasn't exited yet, readd it to the
           end of the queue so we can resume running it
           later */
        shift(sched->queue, sched->current_proc);
    }
    sched->current_proc = pop(sched->queue);
    return sched->current_proc;
}

This is obviously quite simplified (notably excluding/eliding a lot of important stuff like how VM instructions are implemented and how messages get passed), but hopefully it illustrates how (if I'm understanding right, at least) Erlang's preemptive scheduler and process model works on a basic level. 显然,这是相当简化的(特别是排除/消除了很多重要的东西,例如如何实现VM指令以及如何传递消息),但是希望它可以说明(至少在我理解正确的情况下)Erlang的抢先式调度程序和流程模型。在基本水平上工作。

All code of Erlang will compile to operation code of Erlang's VM. Erlang的所有代码都将编译为Erlang VM的操作代码。 Erlang's VM execute Erlang's operation code by OS's threads which are created at startup of Erlang's VM. Erlang的VM通过OS的线程执行Erlang的操作代码,这些线程是在Erlang的VM启动时创建的。

Erlang's code run on Virtual CPUs which are controlled by Erlang's VM. Erlang的代码在由Erlang的VM控制的虚拟CPU上运行。 And Erlang's VM consider IO as interrupt of Virtual CPUs. Erlang的VM将IO视为虚拟CPU的中断。 So Erlang's VM implements a machine and a scheduler like an OS. 因此,Erlang的VM实现了像OS这样的机器和调度程序。 Because of operation code and non-blocking IO, we can implements preempts in Erlang's VM using C languange. 由于操作代码和无阻塞IO,我们可以使用C languange在Erlang的VM中实现抢占。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM