ucontext是linux系统自带的用户级线程上下文,头文件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 m |
将上下文__ucp与执行函数__func关联起来。 |
int setcontext (__const ucontext_t *__ucp) __THROW; |
将上下文设置为指定__ucp。 |
int swa |
进行上下文切换,将当前上下文保存到__oucp中,切换上下文到__ucp。 |
l 基于ucontext的用户级线程实现——uthread
基于ucontext提供的类型与接口实现一个简单的非抢占式的用户级线程uthread,具体包括在uthread.h和uthread.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) bre }
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; m
return 0; }
int uthread_next(){ int i;
if(uthread_current==-1){ for(i=0;i<MAX_UTHREAD_NUM;++i){ if(uthread_slots[i].used) bre } if(i==MAX_UTHREAD_NUM) return -1; else{ uthread_current = i; swa } }else{ for(i=(uthread_current+1)%MAX_UTHREAD_NUM; i!=uthread_current; i=(i+1)%MAX_UTHREAD_NUM){ if(uthread_slots[i].used) bre }
uthread_t uthread_prev = uthread_current; if(i==uthread_current){ uthread_current = -1; swa }else{ uthread_current = i; swa } } 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
|