面向对象程序设计:基于面向对象操作系统开发平台(OSKit)的分析与程序设计(2)来源: 发布时间:星期四, 2009年2月12日 浏览:32次 评论:0
作者:汤海京 线程分析篇的线程化 文是基于面向对象操作系统开发平台(OSKIT)分析和设计第 2篇作者将为我们介绍线程化 前面我们曾经谈到在OSKit中资源分配和调度单位是线程而不是传统意义上进程所以我们有必要花大量时间对其线程机制做全面分析当然要分析线程部分首先应该从线程化入手然后才能涉及到线程间通信以及线程调度所以本章将向各位全面系统地介绍OSKit线程化 2.1 线程化分析 2.1.1线程创建 在OSKit中用户创建个新线程唯思路方法就是创建线程线程pthread_create 内核为系统pthread_create完成如下操作: 为新线程在线程表项中分配个空槽 赋给子线程个唯标识号 制作个父线程上下文逻辑副本由于线程某些部分如正文区可能被几个线程所共享所以内核只要增加某个区引用计数即可而不用真将该区拷贝到个新内存物理区 增加和该线程相关文件表和索引节点表引用数 向父线程返回子线程线程号 系统对个用户可以同时运行线程数有个限制(这个限制是可以改变)因而任何用户不能使用过多线程表项不然话就会妨碍其他用户创建新线程而且OSKit为了防止死锁规定了普通用户不能占用线程表项中最后个线程这条规定是从UNIX中演变而来 2.1.2线程 OSKit线程方案和UNIX十分相似由 3个逻辑段组成它们是正文段、数据段和栈正文段含有个线程所执行指令集合正文段地址包括正文地址(用于分支和子)、数据地址(用于存取全局数据变量)和栈地址(为了存取子数据结构) 若机器将生成地址看作物理存储器中地址那么两个线程在它们所生成地址集合重叠了情况下是不可能并发执行虽然编译器可以产生在的间不重叠地址但这样对于通用计算机是行不通种机器上存储容量是有限而所有可能被编译集合是无限采取此种思路方法可以在很大程度上避免数据丢失 2.1.3线程数据结构 以下我列出了OSKit中线程完整数据结构其中大部分是从UNIX中继承来但也有些是OSKit自己例如为了制作例子所提供CPU资源分配部分 为了使各位目了然我对此数据结构做了全部注释并按照其区别应用领域划分成了几个部分分别加在了下面注释的中 queue_chain_t runq; /* 释放队列链 */ pcb_t *ppcb; /* 指向PCB指针 */ oskit_u32_t *pstk; /* 指向所分配堆栈指针*/ void *(*func)(void *); /* 指向执行指针 */ size_t ssize; /* 所分配堆栈大小*/ size_t guardsize; /* 警戒堆栈大小 */ pthread_t tid; /* 线程号 */ oskit_u32_t flags; /* 线程状态标志 */ pthread_lock_t lock; /* 锁 */ queue_chain_t chain; /* 队列链 */ preempt; /* 线程优先级 */ /*以下用于对死锁处理*/ pthread_mutex_t mutex; /* 互斥位(死锁保护) */ pthread_cond_t cond; /* 等待死锁标志=1 */ dead; /* 死锁了 */ /*例子所用到资源*/ cputime; /* 占用CPU时间 */ cpticks; /* 上秒所占节拍数 */ oskit_u32_t pctcpu; /* CPU占用率 */ childtime; /* 子线程所占用CPU开销 */ /*发送信息所用变量*/ pthread_lock_t waitlock; /* 等待锁*/ oskit_u32_t waitflags; /* 等待标志位 */ pthread_cond_t *waitcond; /* 等待条件变量 */ struct osenv_sleeprec *sleeprec; /*个osenv_sleep中线程 */ /*以下是进程通讯要用到*/ void *msg; /* 指向要发送消息指针 */ oskit_size_t msg_size; /* 消息大小 */ pthread_t tid; /* 线程号 */ void *reply; /* 指向响应信息指针 */ oskit_size_t reply_size; /* 响应内容大小 */ queue_head_t senders; /* 发送队列中发送者 */ queue_chain_t senders_chain; /* 发送队列指针 */ /* 以下是所用到时钟 */ struct oskit_timer *condtimer; /* 线程休眠和唤醒是用个单独计时器实现 */ struct oskit_timer *sleeptimer; /* 以下是所用到信号 */ pthread_lock_t siglock; /* 保护锁信号 */ sig_t sigmask; /* 阻塞信号 */ sig_t sigpending; /* 未决信号 */ sig_t sigwaiting; /* 等待信号信号 */ oskit_u32_t eip; /* 页处理故障信号 */ /* 键值通常是个固定队列 */ void *keyvalues[PTHREAD_KEYS_MAX]; /* 键值 */ /* 以下用于清除操作 */ pthread_cleanup_t *cleanups; /* 清楚操作链 */ char cancelstate; /* 取消状态 */ char canceltype; /* 取消类型 */ /* 以下是单独用于调度锁 */ pthread_lock_t schedlock; void *rtai_priv; policy; /* 调度策略 */ priority; /* 当前优先级 */ struct scheduler_entry *scheduler; /* 调度入口 */ policy; /* 调度策略 */ priority; /* 当前优先级 */ base_priority; /* 优先级 */ ticks; /* 调度所省下节拍 */ oskit_timespec_t start; /* 下次运行时间 */ oskit_timespec_t deadline; /* 下次运行时间 */ oskit_timespec_t period; /* 两次执行见间隔 */ queue_head_t waiters; /* 正在等待线程 */ queue_chain_t waiters_chain; /* 线程队列链 */ struct pthread_thread *waiting_for; /* 所等待线程 */ struct pthread_thread *inherits_from; /* 线程从何继承 */ /*以下是CPU继承*/ struct pthread_thread *scheduler; /* 线程调度人口 */ schedmsg_t unblockmsg; schedmsg_queue_t *msgqueue; sched_wakecond_t wakeup_cond; /* 唤醒条件 */ schedflags_t schedflags; /* 标志 */ donate_rc; /* 从捐赠线程返回值 */ timeout; /* 毫秒 */ queue_head_t donors; /* 捐赠资源线程 */ queue_chain_t donors_chain; /* 捐赠队列链 */ struct pthread_thread *donating_to; /* 被捐赠线程 */ struct pthread_thread *inherits_from; /* 线程从何继承 */ struct pthread_thread *nextup; /* 下个要执行线程 */ 2.2 pthreads/pthread_create.c 此源码文件包括了套完整线程创建机制它是全部线程根源所在通过阅读下面分析将使读者了解OSKit到底是用什么来具体实现线程创建我认为在上节理论指导下对代码进行分析要比泛泛阐述理论更容易让读者接受更能加深在读者脑海中印象 2.2.1 创建线程 介绍说明:这就是我们在第节中提到创建线程所有由用户完成创建线程操作都要它来实现 pthread_create ( pthread_t *tid, const pthread_attr_t *attr, void * ( *function )( void * ), void *argument ) tid: 指向线程存储位置指针 attr: 指向线程属性指针 *(*function)(void *): 当线程化时所 *argument: 功能 2.2.2 创建内部线程 介绍说明:该用于系统核心部分创建核心线程而般用户没有它权利只有系统核心才可以 pthread_thread_t *pthread_create_ernal ( void * ( *function)( void *), void *argument,const pthread_attr_t *attr ) 注:内部线程创建时将阻塞所有信号 sigfill(&pthread->sigmask) 2.2.3 为主进程创建个备份线程 介绍说明:出于系统原因OSKit定义了此用于对主线程进行备份由于线程创建子线程子线程又创建自己子线程如此下去将产生个以主线程为根节点树形结构所以旦主线程丢失将有可能导致系统崩溃所以应对其进行备份 pthread_thread_t *pthread_init_thread ( pthread_thread_t *pthread ) 2.2.4 化创建线程线程 介绍说明:这和UNIX中那个创建进程进程有些类似它唯工作就是为主线程创建子线程并且每个线程都包含个该线程 pthread_thread_t *thread_init_thread ( pthread_thread_t *pthread ) 2.2.5 为等待和休眠线程创建个等待时间 介绍说明:由于调度原因般线程不可能直占用CPU也不可能永远被挂起 0
相关文章
读者评论发表评论 |