厦门易尔通网站建设好吗seo模拟点击
资源下载地址:https://download.csdn.net/download/sheziqiong/85821835
资源下载地址:https://download.csdn.net/download/sheziqiong/85821835
用户级线程库的实现
一、线程库的具体内容
使用线程库前首先要调用 uthread_init()。这个函数只执行一次,负责初始化数据结构,比如全局 uthreads 矩阵和 ut_curthr(当前正在执行的线程)。 uthread_init()中有一些特殊的代码,处理当前正在执行的进程的上下文(即调用 uthread_init()的进程),使其成为一个有效的 uthread,并设置 ut_curthr 为该 uthread,这个 uthread 被称为主线程或 0 号线程。所有事情初始化后,可以使用线程 uthread_create()创建线程。
一旦创建好线程,线程库能够调度这些线程。若线程需要暂时 yield 处理器给另一个线程 (仍然是可执行的,即处于就绪态),则需要调用 uthread_yield()。线程可以通过 uthread_block()进入睡眠态,也可以通过 uthread_wake()被唤醒。uthread_switch()函数负责选择另一个线程运行。调度器调度时,采用优先级调度算法,线程优先级可以由 uthread_setprio()设置,数字越大优先级越高,相同优先级的线程则轮流使用 CPU。每个优先级一个队列,相关的数据结构见 uthread_sched.c 中的 runq_table。
Uthreads 中的线程有 6 种状态,定义如下:
typedefenum{UT_NO_STATE,/*无效的线程状态*/UT_ON_CPU,/*线程正在执行*/UT_RUNNABLE,/*线程可运行,就绪*/UT_WAIT,/*线程被阻塞*/UT_ZOMBIE,/*线程处于 zombie 状态,即已结束,但需要回收资源*/UT_TRANSITION,/*线程处于创建状态*/UT_JOINABLE,//线程结束时需要一个线程回收其资源UT_DETACHABLE,//线程结束时,不需要一个线程回收其资源UT_NUM_THREAD_STATES//线程状态数目} uthread_state_t;
在 uthreads 中永远不会有多于一个线程同时执行,但线程可被抢占。在 uthreads 中,使用 uthread_makecontext()创建线程的机器上下文。如果需要改变当前正在执行线程,需要调用 uthread_swapcontext(),这使得当前 CPU 上下文被保存,新的上下文被执行。保存的上下文作为 newctx 参数在之后调用 uthread_swapcontext()时被重新执行。
Uthread 中有一个线程称之为 Reaper 线程,也就是 1 号线程,负责清理已结束线程占用的资源。值得注意的是 reaper 并不清理已经结束但还没有 joined 的 non-detached 线程,而是让 uthread_join()去完成。
二、实现过程
需要实现的函数如下(更具体的实现思路请看源代码的注释)。
uthread_yield:当前正在运行的线程让出 CPU,线程仍然处于可运行状态,即 UT_RUNNABLE。调用此函数时,当前线程加入到就绪队列,如果当前线程大于系统中已有的最高优先级线程,则直接从 uthread_yield 返回;否则放弃 CPU,转去执行最高优先级的线程。
uthread_wake:唤醒指定的线程,使其可再次被执行(注意:线程有可能已经处于就绪态)。所作的事情:改变状态,将其放入就绪队列。
uthread_setprio:改变指定线程的优先级。注意,如果线程已处于 UT_RUNNABLE 状态(可执行,但没有占有 CPU),则应该改变其优先级队列,如果该指定线程的优先级高于当前调用者,则调用者还要放弃 CPU;如果线程状态为 UT_TRANSITION,则它是一个刚创建的线程(即将第一次被放入就绪队列),将其状态改为 UT_RUNNABLE。成功时返回 1,否则返回 0。
uthread_switch:找到最高优先级的可运行线程,然后使用 uthread_swapcontext()切换到它(注意设置 UT_ON_CPU 线程状态和当前线程)。如果调用线程本身就是最高优先级线程,则切换回调用线程。主要工作:找出系统中优先级最高的线程,并切换(必须要有可执行线程)。
uthread_init:这个函数只在用户进程启动时调用一次,用于初始化所有的全局数据结构和变量。这个函数需要设置每一个线程的 ut_state 和 ut_id,简单起见,本系统中选择线程数组的下标作为 ut_id。
uthread_create:创建一个线程执行指定的函数,函数的参数为和,优先级为。首先,使用uthread_alloc找到一个有效的id,找不到时,返回合适的错误;然后,为线程分配栈,分配不成功时返回合适的错误;使用uthread_makecontext()创建线程的上下文;按照新发现的线程id,设置uthread_t结构,调用uthread_setprio设置线程的优先级,在中返回线程id。不成功时返回0。
uthread_exit:结束当前的线程(注意设置 uthread_t 中的标志)。如果线程是 UT_DETACHABLE,则通过调用 make_reapable()将其放入清理线程(reaper)清理队列并唤醒清理清理线程。如果线程是 UT_JOINABLE,则唤醒等待的线程。然后调用 uthread_switch()切换线程。
uthread_join:等待指定的线程结束,如果线程没有结束执行,调用线程需要阻塞,直到线程结束。主要工作:如果要等待的线程还没有结束,则置线程的等待线程为当前线程,线程状态改为 UT_WAIT,切换线程;如果成功地等到了线程结束,则调用 make_reapable 唤醒清理线程 reaper 将其彻底清理。错误条件及对应的 error code 参考 pthread_join 的 manpage。
uthread_self:返回当前正在执行的线程的 id。
uthread_alloc:找到一个自由的 uthread_t,返回其 id(uthread_id_t)。
uthread_destroy:清理指定的线程。
uthread_cond_init:初始化指定的条件变量。
uthread_cond_wait:等待指定的条件变量。改变当前线程的状态,释放当前线程占有的锁,并将当前线程放入条件变量的等待队列中,切换线程。
uthread_cond_broadcast:唤醒等待于此条件变量的所有线程。
uthread_cond_signal:唤醒等待于此条件变量的一个线程。
uthread_mtx_init:初始化指定的 mutex。
uthread_mtx_lock:如果没有线程占有该锁,则将锁的拥有者改为当前线程,否则,当前阻塞,让出 CPU。
uthread_mtx_trylock:试图上锁 mutex,得到锁时返回 1,否则返回 0。
uthread_mtx_unlock:释放锁。如果有其他线程在等待该锁,则唤醒它。
三、结果分析
资源下载地址:https://download.csdn.net/download/sheziqiong/85821835
资源下载地址:https://download.csdn.net/download/sheziqiong/85821835