📄 2.html
字号:
oskit_u32_t pstk; /*指向所分配的堆栈的指针*/<br>
void *(*func)(void *); /* 指向执行函数的指针*/<br>
size_t ssize; /* 所分配的堆栈的大小*/<br>
size_t guardsize; /*警戒堆栈的大小 */<br>
pthread_t tid; /* 线程号 */<br>
oskit_u32_tflags; /* 线程状态标志 */<br>
pthread_lock_t lock; /* 锁*/<br>
queue_chain_t chain; /* 队列链 */<br>
int preempt; /*线程优先级 */<br>
/*以下用于对死锁的处理*/<br>
pthread_mutex_t mutex; /* 互斥位(死锁保护)*/<br>
pthread_cond_t cond; /* 等待死锁标志=1 */<br>
int dead; /*死锁了 */<br>
/*例子所用到的资源*/<br>
int cputime; /* 占用CPU的时间 */<br>
intcpticks; /* 上一秒所占的节拍数 */<br>
oskit_u32_t pctcpu; /* CPU的占用率*/<br>
int childtime; /* 子线程所占用的CPU的开销*/<br>
/*发送信息所用的变量*/<br>
pthread_lock_t waitlock; /* 等待锁*/<br>
oskit_u32_twaitflags; /* 等待标志位 */<br>
pthread_cond_t *waitcond; /* 等待条件变量*/<br>
struct osenv_sleeprec *sleeprec; /*一个osenv_sleep中的线程*/<br>
/*以下是进程通讯要用到的*/<br>
void *msg; /* 指向要发送的消息的指针*/<br>
oskit_size_t msg_size; /* 消息的大小 */<br>
pthread_t tid; /*线程号 */<br>
void *reply; /* 指向响应信息的指针*/<br>
oskit_size_t reply_size; /* 响应内容的大小*/<br>
queue_head_t senders; /* 发送队列中的发送者 */<br>
queue_chain_tsenders_chain; /* 发送队列指针 */<br>
/* 以下是所用到的时钟 */<br>
structoskit_timer *condtimer;<br>
/* 线程的休眠和唤醒是用一个单独的计时器实现的 */<br>
structoskit_timer *sleeptimer;<br>
/* 以下是所用到的信号 */<br>
pthread_lock_t siglock; /*保护锁信号 */<br>
sigset_t sigmask; /* 阻塞信号*/<br>
sigset_t sigpending; /* 未决信号 */<br>
sigset_t sigwaiting; /*等待信号的信号 */<br>
oskit_u32_t eip; /* 页处理故障信号 */<br>
/* 键值通常是一个固定的队列*/<br>
void *keyvalues[PTHREAD_KEYS_MAX]; /* 键值 */<br>
/* 以下用于清除操作*/<br>
pthread_cleanup_t *cleanups; /* 清楚操作链*/<br>
char cancelstate; /* 取消状态 */<br>
char canceltype; /*取消类型 */<br>
/* 以下是单独用于调度的锁*/<br>
pthread_lock_t schedlock;<br>
void *rtai_priv;<br>
intpolicy; /* 调度策略 */<br>
int priority; /* 当前的优先级 */<br>
structscheduler_entry *scheduler; /* 调度程序入口 */<br>
int policy; /* 调度策略*/<br>
int priority; /* 当前优先级 */<br>
int base_priority; /*初始优先级 */<br>
int ticks; /* 调度所省下的节拍*/<br>
oskit_timespec_t start; /* 下次运行的时间*/<br>
oskit_timespec_t deadline; /* 下次运行的时间*/<br>
oskit_timespec_t period; /* 两次执行见的间隔*/<br>
queue_head_t waiters; /* 正在等待的线程 */<br>
queue_chain_twaiters_chain; /* 线程队列链 */<br>
struct pthread_thread *waiting_for; /* 所等待的线程*/<br>
struct pthread_thread *inherits_from; /* 线程从何继承*/<br>
/*以下是CPU的继承*/<br>
struct pthread_thread *scheduler; /* 线程调度程序人口*/<br>
schedmsg_t unblockmsg;<br>
schedmsg_queue_t *msgqueue;<br>
sched_wakecond_t wakeup_cond;/* 唤醒条件 */<br>
schedflags_t schedflags; /* 标志 */<br>
intdonate_rc; /* 从捐赠线程返回的值 */<br>
int timeout; /* 毫秒*/<br>
queue_head_t donors; /* 捐赠资源的线程 */<br>
queue_chain_tdonors_chain; /* 捐赠队列链 */<br>
struct pthread_thread *donating_to; /* 被捐赠的线程*/<br>
struct pthread_thread *inherits_from; /* 线程从何继承 */<br>
structpthread_thread *nextup; /* 下一个要执行的线程 */<p>
<br>
2.2 pthreads/pthread_create.c<p>
此源码文件包括了一套完整的线程创建机制,它是全部线程的根源所在,通过阅读下面的函数分析,将使读者了解OSKit到底是用什么函数来具体实现线程创建的。我认为在上一节的理论指导下对代码进行分析,要比泛泛的阐述理论更容易让读者接受,更能加深在读者脑海中的印象。<p>
2.2.1 创建线程<br>
说明:这就是我们在第一节中提到的创建线程的函数,所有由用户完成的创建线程的操作,都要调用它来实现。<br>
intpthread_create ( pthread_t *tid, const pthread_attr_t *attr,<br>
void * (*function )( void * ), void *argument )<br>
tid: 指向线程存储位置的指针<br>
attr:指向线程属性的指针<br>
*(*function)(void *): 当线程初始化时所调用的函数<br>
*argument: 函数功能<p>
2.2.2创建内部线程<br>
说明:该函数用于系统核心部分创建核心线程,而一般的用户没有调用它的权利,只有系统核心才可以调用。<br>
pthread_thread_t*pthread_create_internal ( void * ( *function)( void *), void *argument,constpthread_attr_t *attr)<br>
注:内部线程创建时,将阻塞所有的信号<br>
sigfillset(pthread->sigmask)<p>
2.2.3为主进程创建一个备份线程<br>
说明:出于系统安全的原因,OSKit定义了此函数,用于对主线程进行备份。由于线程创建子线程,子线程又创建自己的子线程,如此下去,将产生一个以主线程为根节点的树形结构,所以一旦主线程丢失,将有可能导致系统崩溃,所以应对其进行备份。<br>
pthread_thread_t*pthread_init_mainthread ( pthread_thread_t *pthread )<p>
2.2.4初始化创建线程的线程<br>
说明:这和UNIX中那个创建进程的进程有些类似,它唯一的工作就是为主线程创建子线程,并且,每个线程都包含一个该线程。<br>
pthread_thread_t*thread_init_mainthread ( pthread_thread_t *pthread )<p>
2.2.5为等待和休眠的线程创建一个等待时间<br>
说明:由于调度的原因,一般线程不可能一直占用CPU,也不可能永远被挂起,所以OSKit为规定线程的等待时间定义了此函数。<br>
voidpthread_prepare_timer ( pthread_thread_t *pthread )<p>
<br>
2.3 pthreads/pthread_attr.c<p>
此源码文件包括了一套完整的线程属性的初始化机制,它与上一节的线程创建共同作用,规定了线程在创建之初的属性,通过阅读下面的函数分析,将使读者了解OSKit到底是用什么函数来具体实现线程属性的初始化。<p>
2.3.1线程初始化的数据结构<br>
说明:系统在创建新线程的时候,会调用此函数来规定被创建线程的属性,所以此函数在线程属性机制中站有最主要的地位,是一切线程属性函数调用的源泉,希望读者给以充分的重视。<br>
intpthread_attr_init ( pthread_attr_t *attr )<br>
attr->detachstate =PTHREAD_CREATE_JOINABLE; /* 线程与其他线程关联*/<br>
attr->priority =PRIORITY_NORMAL; /* 线程的优先级 */<br>
attr->stacksize = PTHREAD_STACK_MIN; /*线程所占堆栈的 */<br>
attr->guardsize = DEFAULT_STACKGUARD; /* 警戒堆栈的大小 */<br>
attr->stackaddr = 0; /* 堆栈的大小 */<br>
attr->policy = SCHED_RR; /*线程调度类型 */<br>
attr->inherit = PTHREAD_EXPLICIT_SCHED; /* 线程继承类型 */<br>
注:memset 的数据结构 /* \oskit\libc\string\memset.c */<br>
void *memset(void *tov, intc, size_t len)<br>
{ register char *to = tov;<br>
while (len-- >0)<br>
*to++ = c;<br>
return tov;<br>
}<br>
tov: 指向内存的首地址 c: 分配类型 len:分配长度<p>
2.3.2线程属性的撤销<br>
说明:这个函数是上一个函数的逆操作,在撤销一个线程的同时,其属性也应相应地被撤销,所以OSKit定义了此函数来实现该功能。<br>
intpthread_attr_destroy ( pthread_attr_t *attr )<br>
memset((void *) attr, -1,sizeof(*attr)); /* 撤销指针并释放内存*/<p>
2.3.3设置线程的警戒堆栈大小<br>
说明:警戒堆栈在操作系统中被广泛使用,它是源于UNIX的进程间通信,在UNIX系统中,接受进程的消息缓冲可能小于发送进程。所以,当消息到来的时候,为了避免溢出造成的信息丢失,系统创建了警戒堆栈,用来存储溢出的消息。而OSKit把它用于线程间通信的保护,但用法与UNIX大同小异。<br>
intpthread_attr_setguardsize ( pthread_attr_t *attr, size_t guardsize )<p>
2.3.4得到警戒堆栈的大小<br>
说明:由于OSKit为每个接受线程设置警戒堆栈,所以定义此函数,为的是系统能方便的得到每个接受线程的警戒堆栈的大小,这同样是出于对安全的考虑。<br>
intpthread_attr_getguardsize ( const pthread_attr_t *attr, size_t *guardsize )<p>
2.3.5设置线程的分离状态<br>
说明:上边曾经提到,系统中的线程树,而线程与线程之间很可能并不是完全独立的,即使他们处于不同的层次,也可能有一定的相关性或互斥性,所以定义此函数用来规定线程之间的互斥性,即分离状态是完全有必要的。<br>
intpthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )<p>
2.3.6得到线程的分离状态<br>
说明:在规定了分离状态之后,若A线程要与B线程发生关联的时候,它必须先看看B线程和其他线程的关系,所以要定义此函数来得到B线程与其他线程的分离状态,提供给A,然后A在根据具体情况决定是否与B发生关系。<br>
intpthread_attr_getdetachstate ( const pthread_attr_t *attr, int *detachstate)<br>
*detachstate = attr->detachstate;<p>
2.3.7设置线程的继承关系<br>
说明:当线程创建子线程的时候,上边我提到的那个创建线程的线程会为他们父子之间规定继承关系,即子线程继承父线程。<br>
intpthread_attr_setinheritsched ( pthread_attr_t *attr, int inheritstate)<br>
attr->inherit = inheritstate;<p>
2.3.8得到线程的继承状态<br>
说明:当系统要在复杂的线程树中得到继承关系的时,调用此函数便能达到预期的目的。OSKit定义此函数,为的是能在复杂的线程树中一眼看穿某两个线程之间的关系。<br>
intpthread_attr_getinheritsched ( const pthread_attr_t *attr, int *inheritstate)<br>
*inheritstate = attr->inherit;<p>
2.3.9设置线程的调度参数<br>
说明:OSKit提供了多种线程调度方式供选择,而且还为每个线程在创建的时候规定了一种调度算法,系统在创建线程的时候调用下面的函数来完成这项工作。<br>
intpthread_attr_setschedparam ( pthread_attr_t *attr,const struct sched_param*param )<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -