从线程返回控制器到调度器(上下文切换)

我正在为一个大学项目使用上下文切换编写一个简单的线程库。 我有从线程执行返回的麻烦。

最初我切换到这样一个新创build的线程:

int done = 0; getcontext(&parent_context); if (!done) { done = 1; setcontext(&(thread->context)); } return thread->tid; 

其中&parent_context thread->context.uc_link&parent_context 。 它可以工作,但是我需要在线程创build时调用一个调度器,而不是仅仅切换到上下文。 所以我将thread->context.uc_link设置为NULL而不是&parent_context并用上面的代码replace

 schedule(thread); scheduler(); return thread->tid; 

schedule队列线程和scheduler获取队列中的第一个线程并调用dispatcher ,这只是一个调用setcontext 。 事情是,我需要线程返回到调度程序的控制。 我发生的第一件事是做:

 static void scheduler() { int dispatched = 0; ucontext_t ret; // Get the first thread in the queue, then thread->context.uc_link = &ret; getcontext(&ret); if (!dispatched) { dispatched = 1; setcontext(&(thread->context)); } // Remove the dispatched thread from the queue } 

哪个不工作 – 线程不会将控制权返回给调度程序,程序在线程终止执行后结束。 我认为这是因为我改变uc_link后没有调用makecontext 。 然而,为了调用makecontext我将不得不传递给调度器的线程的函数指针和参数,这是不可取的,因为我不能修改线程数据结构来存储(项目规则)。 使用上下文切换的线程“库”在线上find在线程函数内执行setcontext调用:

http://www.evanjones.ca/software/threading.html

http://nitish712.blogspot.com.br/2012/10/thread-library-using-context-switching.html

这也是不可取的,因为用户不需要自己做上下文切换。 我怎样才能使线程返回到调度程序的控制? 我可以想到的一个破解是使用一个静态variablesucontext_t return_context并使用它作为所有线程的uc_link 。 所以在我调用调度程序之前,我先调用getcontext(&return_context) ,调度程序变成:

  // Get the first thread in the queue, then // Remove the thread from the queue setcontext(&(thread->context)); 

这似乎工作,但这样,没有两个线程可以同时执行。 这个项目不是问题,但似乎是错误的。 另一个问题是调用调度程序的每个函数都起着调度程序的作用:

 int done = 0; getcontext(&return_context); if (!done) { done = 1; scheduler(); } fprintf(stderr, "Thread returned\n"); 

这是要走的路吗?

代码需要做什么取决于代码运行的环境。

如果在像Linux,MAC或Windows这样的操作系统下运行,用户实际上并没有太多的控制权。

如果在“准系统”平台上运行,则需要做出以下选择:

先占上下文切换或许可上下文切换。

在先发制人的上下文切换中,中断处理程序触发调度程序(这将触发调度程序,这实际上会导致“线程”恢复执行),调度程序保存当前上下文,决定接下来要运行什么(这取决于如何自从线程运行以来,以及可用上下文的优先级,以及在等待某个事件时特定上下文被“阻塞”的地方。

在宽松的上下文切换中,线程调用调度器,从而放弃CPU到调度器,这将恢复哪个线程没有被阻塞并且最高优先级被延迟最长。

在时间敏感的系统中,调度程序还将检查需要定期运行的线程在重新启动该线程之前是否已经完成其先前的执行。 如果线程没有完成其先前的执行,则会产生错误,通常包括记录错误并重新启动系统。

那么,你的代码应该运行在什么样的环境?