现在的位置: 首页 > 综合 > 正文

基于ucontex实现用户级线程

2013年09月11日 ⁄ 综合 ⁄ 共 4495字 ⁄ 字号 评论关闭

ucontextlinux系统自带的用户级线程上下文,头文件ucontext.h。我们可以用它来实现自定义的用户级线程。

l  基本类型

(1) ucontext_t类型

typedef struct ucontext                        //用户级线程上下文

{

unsigned long int uc_flags;

struct ucontext *uc_link;                    //保存线程退出时返回的上下文

stack_t uc_stack;                          //线程栈

mcontext_t uc_mcontext;

__sigset_t uc_sigmask;

struct _libc_fpstate __fpregs_mem;

} ucontext_t;

(2) stack_t

typedef struct sigaltstack {

void *ss_sp;                             //栈顶指针

int ss_flags;

size_t ss_size;                            //栈大小

} stack_t;

 

l  用户接口

接口

说明

int getcontext (ucontext_t *__ucp) __THROW;

获取用户上下文,并存储到用户指定的ucontext_t类型变量__ucp中。

void makecontext (ucontext_t *__ucp, void (*__func) (void),                         int __argc, ...) __THROW;

将上下文__ucp与执行函数__func关联起来。

int setcontext (__const ucontext_t *__ucp) __THROW;

将上下文设置为指定__ucp

int swapcontext (ucontext_t *__restrict __oucp,                        __const ucontext_t *__restrict __ucp) __THROW;

进行上下文切换,将当前上下文保存到__oucp中,切换上下文到__ucp

 

l  基于ucontext的用户级线程实现——uthread

基于ucontext提供的类型与接口实现一个简单的非抢占式的用户级线程uthread,具体包括在uthread.huthread.cpp文件中。

uthread.h定义如下:

#ifndef _UTHREAD_H

#define _UTHREAD_H

 

#include <stdlib.h>

#include <stdio.h>

#include <ucontext.h>

 

#define STACK_SIZE 4096

#define MAX_UTHREAD_NUM 256

 

typedef int uthread_t;

typedef void uthread_attr_t;

 

struct uthread_struct{

    int used;                               //线程slot使用标记

    ucontext_t context;                       //上下文

    char stack[STACK_SIZE];                 //线程栈

    void* (*func)(void *arg);                  //线程函数

    void *arg;                              //线程函数参数

    void *exit_status;                        //线程退出状态

};

 

static uthread_t uthread_current = -1;                            //指示当前线程号,-1表示主线程

static ucontext_t main_context;                                 //主线程的context

static struct uthread_struct uthread_slots[MAX_UTHREAD_NUM];    //线程slot

 

void uthread_context_init(int tid);

int uthread_create(uthread_t *thread, const uthread_attr_t *attr, void* (*start_routine)(void*), void *arg);

int uthread_next();

void uthread_exit(void *exit_status);

void uthread_run();

uthread_t uthread_self();

 

#endif //_UTHREAD_H//

      

uthread.cpp实现如下:

#include "uthread.h"

 

void uthread_context_init(int tid){

         getcontext(&uthread_slots[tid].context);

  uthread_slots[tid].context.uc_stack.ss_sp = uthread_slots[tid].stack;

  uthread_slots[tid].context.uc_stack.ss_size = sizeof(uthread_slots[tid].stack);

  uthread_slots[tid].context.uc_link = NULL;

}

 

int uthread_create(uthread_t *thread, const uthread_attr_t *attr, void* (*start_routine)(void*), void *arg){

  int i;

  for(i=0; i<MAX_UTHREAD_NUM;++i){

       if (!uthread_slots[i].used) break;

  }

 

  if (i==MAX_UTHREAD_NUM)

       return -1;

 

  if (thread != NULL)

       *thread = i;

  uthread_context_init(i);

  uthread_slots[i].used = 1;

  uthread_slots[i].func = start_routine;

  uthread_slots[i].arg = arg;

  uthread_slots[i].exit_status = 0;

  makecontext(&uthread_slots[i].context, uthread_run, 0);

 

  return 0;

}

 

int uthread_next(){

         int i;

        

         if(uthread_current==-1){

                   for(i=0;i<MAX_UTHREAD_NUM;++i){

                            if(uthread_slots[i].used) break;

                   }

                   if(i==MAX_UTHREAD_NUM) return -1;

                   else{

                            uthread_current = i;

                            swapcontext(&main_context, &uthread_slots[uthread_current].context);

                   }

         }else{

                   for(i=(uthread_current+1)%MAX_UTHREAD_NUM; i!=uthread_current; i=(i+1)%MAX_UTHREAD_NUM){

                            if(uthread_slots[i].used) break;

                   }

                  

                   uthread_t uthread_prev = uthread_current;

                   if(i==uthread_current){       

                            uthread_current = -1;

                            swapcontext(&uthread_slots[uthread_prev].context, &main_context);

                   }else{

                            uthread_current = i;

                            swapcontext(&uthread_slots[uthread_prev].context, &uthread_slots[uthread_current].context);

                   }

         }

         return 0;

}       

        

void uthread_exit(void *exit_status){

         uthread_slots[uthread_current].exit_status = exit_status;

  uthread_slots[uthread_current].used = 0;

  uthread_t uthread_prev = uthread_current;

  uthread_next();

}       

        

void uthread_run(){

         uthread_exit(uthread_slots[uthread_current].func( uthread_slots[uthread_current].arg));

}       

        

uthread_t uthread_self(){

         return uthread_current;

}

 

uthread目前提供以下一些类型和接口:

宏定义

STACK_SIZE

线程栈大小

MAX_UTHREAD_NUM

用户级线程最大个数

类型

uthread_t

uthread线程ID

编程接口

int uthread_create(uthread_t *thread, const uthread_attr_t *attr, void* (*start_routine)(void*), void *arg);

创建线程,thread

抱歉!评论已关闭.