📄 2.html
字号:
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> int pri = param->priority;<br> attr->start =param->start; /* 线程开始参数 */<br> attr->period = param->period; /*线程的周期 */<br> attr->deadline = param->deadline; /* 线程运行的最终时限 */<p>2.3.10得到线程调度的参数<br>说明:在OSKit中,每个线程都有其自身的调度方式,换句话说,就是线程的调度方式仿佛是线程的一个属性,在创建线程的时候就随线程被规定了,所以调度程序可以通过下面的函数来得到某个线程的调度算法和此时它的优先级。<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -