线程

来自SylixOS-wiki
(版本间的差异)
跳转至: 导航, 搜索
(一分钟实验)
 
(未显示1个用户的20个中间版本)
第1行: 第1行:
==线程知识==
+
==线程==
 +
:线程是程序中的一条独立的控制流,线程是SylixOS调度器进行任务调度的基本单位,每个线程都有一个独一无二的ID号、栈、线程控制块(TCB)。
  
===基本概念===
+
为了管理线程,SylixOS会为每一个线程分配一个线程控制块,用于记录该线程的信息,如线程入口函数、线程优化级、线程名字、线程当前的堆栈指针等。
  
:一般来说,我们把正在计算机中执行的程序叫做“进程”(Process) ,而不将其称为程序(Program)。所谓“线程”(Thread),是“进程”中某个单一顺序的控制流。
+
:线程入口函数可以调用其它函数,函数内定义的局部变量将从它自己的栈里分配,所以不同的线程可以有相同的线程入口函数,但又独立运行。
  
:新兴的操作系统,大多采用多线程的概念,把线程视为基本执行单位,也是操作系统进行任务调度的基本单位。
+
:线程栈可以由用户自己分配,也可以操作系统代为分配,线程栈的大小不应改过少(容易造成栈溢出),也不应该过大(造成浪费)。
  
===发展历史===
+
:线程ID在线程被创建时决定,是线程的标识符。
  
:60年代,在操作系统中能拥有资源和独立运行的基本单位是进程,然而随着计算机技术的发展,进程出现了很多弊端,一是由于进程是资源拥有者,
+
:线程优先级和调度策略是SylixOS调度器进行任务调度的参数,SylixOS是一个实时操作系统(RTOS),始终运行一个优先级最高的就绪态任务。
  
创建、撤消与切换存在较大的时空开销,因此需要引入线程;二是由于对称多处理器(SMP)出现,可以并行地运行多个执行单位,而多个进程并行开销过大。
+
==线程的基本状态==
 +
:线程的基本状态有如下几种:
  
因此在80年代,出现了能独立运行的基本单位——线程(Thread)。
+
:1. 初始化          创建线程过程中线程的状态
 +
:2. 就绪            线程可以运行的状态
 +
:3. 等待            线程需要等行某些事件而不能继续的状态
 +
:4. 僵死状态        线程退出后处理的状态
  
===工作原理===
+
==线程优先级==
 +
:线程优先级的范围处决于操作系统的配置,默认是0~255,0是最高优先级,255是最低优先级:
  
:线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,只有拥有一些必须的数据结构;它与父进程的其它线程共享
+
#define LW_PRIO_HIGHEST        0                                      /*  SylixOS 最高优先级          */
 +
#define LW_PRIO_LOWEST          255                                    /*  SylixOS 最低优先级          */
 +
 +
/*********************************************************************************************************
 +
  优先级 (一般应用的最高优先级不能高于 LW_PRIO_CRITICAL 最低不能低过 LW_PRIO_LOW)
 +
*********************************************************************************************************/
 +
 +
#define LW_PRIO_EXTREME        LW_PRIO_HIGHEST                        /*  最高优先级                  */
 +
#define LW_PRIO_CRITICAL        50                                      /*  关键处理任务                */
 +
#define LW_PRIO_REALTIME        100                                    /*  实时处理任务                */
 +
#define LW_PRIO_HIGH            150                                    /*  高优先级任务                */
 +
#define LW_PRIO_NORMAL          200                                    /*  正常优先级                  */
 +
#define LW_PRIO_LOW            250                                    /*  低优先级                    */
 +
#define LW_PRIO_IDLE            LW_PRIO_LOWEST                          /*  最低优先级                  */
  
该进程所拥有的全部资源。进程可以创建和撤消线程,从而实现程序的并发执行。
+
==线程调度策略==
 +
:SylixOS支持同优先级线程,同优先级线程的调度策略取决于当前线程的调度策略,如果当前线程的调度策略为先来先服务(FIFO),
  
:就象进程一样,线程在程序中是独立的、并发的执行路径,每个线程有它自己的堆栈、自己的程序计数器和自己的局部变量。但是,与分隔的进程相比,
+
那么必须等当前线程的阻塞时,同优先级的其它线程才有机会运行;如果当前线程的调度策略为轮转(RR),
  
进程中的线程之间的隔离程度要小,它们共享内存、文件句柄等。
+
则当当前线程的时间片用完时或当前线程的阻塞时,同优先级的其它线程才有机会运行。
  
:进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,
+
#define  LW_OPTION_SCHED_FIFO                          0x01            /*  调度器 FIFO                */
 +
#define  LW_OPTION_SCHED_RR                            0x00            /*  调度器 RR                  */
  
而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但您必须小心,确保它们不会妨碍同一进程里的其它线程。
+
==线程相关 API==
 +
:SylixOS 提供了一套 POSIX 线程 API,其接口定义和行为完全符合 POSIX 线程标准,方便了现有 POSIX 程序移植到 SylixOS 上,
  
:一般,线程具有就绪、阻塞和运行三种基本状态。
+
关于 POSIX 线程的编程,市面上有很多书籍,网上也已经有很多资料,这里不再详述,POSIX 线程的编程可以参考这篇文章 https://computing.llnl.gov/tutorials/pthreads/
  
:在对称多处理器(SMP)的系统里,不同线程可以同时在不同的处理器上运行,甚至当它们属于同一个进程时也是如此。大多数支持多处理器的操作系统都提供编程接口
+
:SylixOS 系统内部线程 API 的命名一般以 API_Thread 开始,API 的声明位于 libsylixos/SylixOS/kernel/include/k_api.h 文件,
  
来让进程可以控制自己的线程与各处理器之间的亲和度(affinity)。
+
为了适应不同语言习惯的人,也提供了一套以 Lw_ 开头的 API,请查看 libsylixos/SylixOS/api 目录下的头文件。
  
===相关概念===
+
==内部线程 API 相关的数据类型==
  
===优势===
+
线程句柄  LW_OBJECT_HANDLE
 +
线程 ID  LW_OBJECT_ID
 +
线程属性  LW_CLASS_THREADATTR,*PLW_CLASS_THREADATTR
 +
线程函数  PTHREAD_START_ROUTINE
  
===与进程的比较===
+
:其中 线程函数 PTHREAD_START_ROUTINE 的类型需要理解,它被定义为如下的函数指针:
 +
typedef PVOID      (*PTHREAD_START_ROUTINE)(PVOID pvArg);              /*  系统线程类型定义            */
  
:进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块(PCB)中。以表示该进程拥有这些资源或正在使用它们。
+
:所以线程函数一般形如:
 +
PVOID  thread_func (PVOID pvArg)
 +
{
 +
    // do thing...
 +
    return  NULL;
 +
}
  
另外,进程拥有一个完整的虚拟地址空间。
+
==一分钟实验==
  
:与进程相对应,线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。当进程发生调度时,
+
#include <SylixOS.h> // 包含 SylixOS.h 头文件
 
+
不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。
+
/*
 
+
  * 测试用线程函数
:线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制块(TCB)组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。
+
  */
 
+
PVOID  TestThread (PVOID  pvArg)
:进程切换时涉及到有关资源指针的保存以及地址空间的变化等问题;线程切换时,由于同不进程内的线程共享资源和地址空间,
+
{
 
+
while (1) {
将不涉及资源信息的保存和地址空间变化的问题,从而减少了操作系统的开销时间。
+
printf("hello in thread\n");
 
+
sleep(1);
===适用范围===
+
}
 
+
}
:典型的应用:
+
:1. 服务器中的文件管理或通信控制
+
LW_OBJECT_HANDLE  hThread; // 定义线程句柄
:2. 前后台处理
+
 
:3. 异步处理
+
hThread = API_ThreadCreate("t_test", TestThread, NULL, NULL); // 创建一个名为 t_test 的线程,线程函数为 TestThread,使用默认的线程属性,不接收线程 ID
 
+
===基本操作===
+
:*创建(Create):线程在进程内创建出来,它可由进程创建,也可由线程创建。
+
 
+
:*阻塞(Block):如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。
+
 
+
:*激活(unblock):如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。
+
 
+
:*调度(schedule):选择一个就绪线程进入执行状态。
+
 
+
:*结束(Finish):如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。
+
 
+
:*线程的另一个执行特性是同步。线程中所使用的同步控制机制与进程中所使用的同步控制机制相同。
+

2015年5月28日 (四) 19:53的最后版本

目录

[编辑] 线程

线程是程序中的一条独立的控制流,线程是SylixOS调度器进行任务调度的基本单位,每个线程都有一个独一无二的ID号、栈、线程控制块(TCB)。

为了管理线程,SylixOS会为每一个线程分配一个线程控制块,用于记录该线程的信息,如线程入口函数、线程优化级、线程名字、线程当前的堆栈指针等。

线程入口函数可以调用其它函数,函数内定义的局部变量将从它自己的栈里分配,所以不同的线程可以有相同的线程入口函数,但又独立运行。
线程栈可以由用户自己分配,也可以操作系统代为分配,线程栈的大小不应改过少(容易造成栈溢出),也不应该过大(造成浪费)。
线程ID在线程被创建时决定,是线程的标识符。
线程优先级和调度策略是SylixOS调度器进行任务调度的参数,SylixOS是一个实时操作系统(RTOS),始终运行一个优先级最高的就绪态任务。

[编辑] 线程的基本状态

线程的基本状态有如下几种:
1. 初始化 创建线程过程中线程的状态
2. 就绪 线程可以运行的状态
3. 等待 线程需要等行某些事件而不能继续的状态
4. 僵死状态 线程退出后处理的状态

[编辑] 线程优先级

线程优先级的范围处决于操作系统的配置,默认是0~255,0是最高优先级,255是最低优先级:
#define LW_PRIO_HIGHEST         0                                       /*  SylixOS 最高优先级          */
#define LW_PRIO_LOWEST          255                                     /*  SylixOS 最低优先级          */

/*********************************************************************************************************
  优先级 (一般应用的最高优先级不能高于 LW_PRIO_CRITICAL 最低不能低过 LW_PRIO_LOW)
*********************************************************************************************************/

#define LW_PRIO_EXTREME         LW_PRIO_HIGHEST                         /*  最高优先级                  */
#define LW_PRIO_CRITICAL        50                                      /*  关键处理任务                */
#define LW_PRIO_REALTIME        100                                     /*  实时处理任务                */
#define LW_PRIO_HIGH            150                                     /*  高优先级任务                */
#define LW_PRIO_NORMAL          200                                     /*  正常优先级                  */
#define LW_PRIO_LOW             250                                     /*  低优先级                    */
#define LW_PRIO_IDLE            LW_PRIO_LOWEST                          /*  最低优先级                  */

[编辑] 线程调度策略

SylixOS支持同优先级线程,同优先级线程的调度策略取决于当前线程的调度策略,如果当前线程的调度策略为先来先服务(FIFO),

那么必须等当前线程的阻塞时,同优先级的其它线程才有机会运行;如果当前线程的调度策略为轮转(RR),

则当当前线程的时间片用完时或当前线程的阻塞时,同优先级的其它线程才有机会运行。

#define  LW_OPTION_SCHED_FIFO                           0x01            /*  调度器 FIFO                 */
#define  LW_OPTION_SCHED_RR                             0x00            /*  调度器 RR                   */

[编辑] 线程相关 API

SylixOS 提供了一套 POSIX 线程 API,其接口定义和行为完全符合 POSIX 线程标准,方便了现有 POSIX 程序移植到 SylixOS 上,

关于 POSIX 线程的编程,市面上有很多书籍,网上也已经有很多资料,这里不再详述,POSIX 线程的编程可以参考这篇文章 https://computing.llnl.gov/tutorials/pthreads/

SylixOS 系统内部线程 API 的命名一般以 API_Thread 开始,API 的声明位于 libsylixos/SylixOS/kernel/include/k_api.h 文件,

为了适应不同语言习惯的人,也提供了一套以 Lw_ 开头的 API,请查看 libsylixos/SylixOS/api 目录下的头文件。

[编辑] 内部线程 API 相关的数据类型

线程句柄  LW_OBJECT_HANDLE
线程 ID   LW_OBJECT_ID
线程属性  LW_CLASS_THREADATTR,*PLW_CLASS_THREADATTR
线程函数  PTHREAD_START_ROUTINE
其中 线程函数 PTHREAD_START_ROUTINE 的类型需要理解,它被定义为如下的函数指针:
typedef PVOID       (*PTHREAD_START_ROUTINE)(PVOID pvArg);              /*  系统线程类型定义            */
所以线程函数一般形如:
PVOID  thread_func (PVOID pvArg)
{
   // do thing...
   return  NULL;
}

[编辑] 一分钟实验

#include <SylixOS.h> // 包含 SylixOS.h 头文件

/*
 * 测试用线程函数
 */
PVOID  TestThread (PVOID  pvArg)
{
	while (1) {
		printf("hello in thread\n");
		sleep(1);
	}
}

LW_OBJECT_HANDLE  hThread; // 定义线程句柄
 
hThread = API_ThreadCreate("t_test", TestThread, NULL, NULL); // 创建一个名为 t_test 的线程,线程函数为 TestThread,使用默认的线程属性,不接收线程 ID
个人工具
名字空间

变种
操作
导航
工具