代码之家  ›  专栏  ›  技术社区  ›  Aillyn

用户空间中的线程和产量

  •  4
  • Aillyn  · 技术社区  · 15 年前

    我应该在C中实现一个用户级线程库 yield() , createThread() destroyThread() 功能。我相信我的基本知识是对的:

    为了跟踪线程,我将使用 ThreadControlBlock 元素(类似 PCBs 在操作系统中)如下所示:

    struct ThreadControlBlock { 
        int ThreadId, 
        u_context *context };
    

    我们可以使用 setcontext() 用于“保存”和“加载”上下文的函数族。 初始化程序后,初始化没有元素的ThreadQueue。

    ,我获取当前上下文并将其保存在 然后排队。然后获取队列中的第一个元素并加载其中的上下文,然后继续执行。

    问题是,如果我这样做,就说我是线程调用 收益率() ?) 这会一直持续下去吗?

    4 回复  |  直到 15 年前
        1
  •  0
  •   caf    15 年前

    同样的问题实际上也适用于切换到另一个任务的情况,因为另一个任务在同一点保存了它的上下文(它将要切换到第二个任务)。使用 setcontext() getcontext() ,您需要使用一个静态变量来跟踪您是在切换还是在切换:

    static volatile int switched;
    
    switched = 0;
    getcontext(current->context);
    if (!switched)
    {
       switched = 1;
       setcontext(next->context);
    }
    

    或者,你可以使用 swapcontext(current->context, next->context);

        2
  •  1
  •   nmichaels    15 年前

    当线程调用 yield() ,则必须保存即将从 打电话。不要在 收益率()

        3
  •  0
  •   Aaron Klotz    15 年前

    你的话很合理 yield() 实现来检查下一个线程是否是当前线程,并将该情况视为禁止操作。

        4
  •  0
  •   nategoose    15 年前

    如果除了当前线程之外没有其他线程可以运行,那么除了从yield返回之外就没有别的事情可做了。不过,在这种情况下,我不需要调用swapcontext——只要检测并返回。

    我认为您实际上要处理的是在调用yield时没有线程(包括当前线程)时要做什么。处理这个问题的一个简单方法是拥有一个空闲线程,它只在运行队列(就绪线程)为空时运行。此线程可能只是:

       {
           while (1) {
               yield();
               pause();
           }
       }
    

    这允许您的程序进入睡眠状态(通过暂停),直到信号发生。希望该信号将是使其他线程之一准备运行的某个事件,因此下一个yield调用将运行另一个线程,而不是再次运行空闲线程。