Win2Linux 线程管理映射

来源:互联网 发布:烟台erp软件 编辑:程序博客网 时间:2024/05/21 22:50

 

尽管Linux系统内核对象在实现和结构上与Windows有很大的不同。但Linux系统调用提供了和Windows的API相似的对内核对象操作的接口。在进程控制,线程管理,调度优先级,同步以及IPC的实现都存在着映射关系。以下一一列举线程管理方面的映射。

与进程控制相比,线程的控制和调度更为简单和灵活。在一般实现中,进程主要作为系统资源分配的单元,线程更主要是作为任务调度的单元。在Linux的中pthread是POSIX中的一个可选特征,在程序链接时必须使用-thread选项,使目标程序支持pthread线程。

创建线程

Windows API声明

 +----------------------------------------------------------------------------------------
| //创建一个新线程,返回线程对象的HANDLE。
| //线程创建标志:0-创建后激活 CREATE_SUSPENDED 创建后挂起
| //CREATE_SUSPENDED:线程创建后不会运行,需要ResumeThread使其运行。
| //线程执行函数原型:long start(void *);
| HANDLECreateThread(
| LPSECURITY_ATTRIBUTESlpThreadAttributes,//
| SIZE_TdwStackSize,// 线程的栈大小
| LPTHREAD_START_ROUTINElpStartAddress,// 线程执行的函数地址
| LPVOIDlpParameter,// 线程执行函数的参数
| DWORDdwCreationFlags,//
| LPDWORDlpThreadId
| };
+---------------------------------------------------------------------------------------+

Linux系统调用原型

 +----------------------------------------------------------------------------------------
| //#include <pthread.h>
| int pthread_create(
| pthread_t *tidp,//线程标识
| const pthread_attr_t *attr,//线程属性
| void *(*start_rtn)(void *),//线程执行函数地址
| void *arg//线程执行函数参数
| );
+---------------------------------------------------------------------------------------+

要修改线程的默认属性(如栈大小)要先初始化和修改线程属性(pthread_attr_t),然后做为线程参数。Linux下线程可修改属性包括线程的栈大小(stacksize),栈最低地址(stackaddr),分离状态(detachstate)以及警戒缓冲区大小(guardsize)。

 +---------------------------------------------------------------------------------------+ 
| //#include <pthread.h>
| //创建并初始化线程属性结构
| int pthread_attr_init(pthread_attr_t *attr);
| int pthread_attr_destroy(pthread_attr_t *attr);
|
| //#include <pthread.h>
| //改变栈的默认大小
| int pthread_attr_getstacksize(
| const pthread_attr_t *attr,
| size_t *stacksize
| );
| int pthread_attr_setstacksize(
| const pthread_attr_t *attr,
| size_t stacksize
| );
+----------------------------------------------------------------------------------------
| //#include <pthread.h>
| //线程的栈可以是进程的虚拟地址空间,也可以是malloc分配的空间地址。
| int pthread_attr_getstack(
| const pthread_attr_t*attr,
| void**stackaddr,
| size_t*stacksize
| );
| int pthread_attr_setstack(
| const pthread_attr_t*attr,
| void*stackaddr,
| size_tstacksize
| );
+---------------------------------------------------------------------------------------+
| //#include <pthread.h>
| //设置线程的分离状态
| //该属性可以是PTHREAD_CREATE_JOINABLE(默认)或PTHREAD_CREATE_DETACHED
| //joinable:线程可以被等待,可以获得线程的返回值,然后回收。
| //detached:线程结束时,使用的资源立马就会释放,不用其他线程等待。
| int pthread_attr_getdetachstate(
| const pthread_attr_t *attr,
| int *detachstate
| );
| int pthread_attr_setdetachstate(
| const pthread_attr_t *attr,
| int detachstate
| );
+----------------------------------------------------------------------------------------
| //#include <pthread.h>
| //guradsize控制着线程栈末尾用以避免栈溢出的扩展内存大小
| int pthread_attr_getguardsize(
| const pthread_attr_t*attr,
| size_t*guradsize
| );
| int pthread_attr_setguardsize(
| const pthread_attr_t*attr,
| size_tguradsize
| );
+---------------------------------------------------------------------------------------+

终止线程

Windows API声明

 +----------------------------------------------------------------------------------------
| //终止线程,并将dwExitCode做为线程返回值。
| //线程返回值可以通过GetExitCode()方法被其它线程获取。
| VOID ExitThread(
| DWORDdwExitCode// 线程终止码
| );
| DWORD GetExitCode();
+---------------------------------------------------------------------------------------+

Linux 系统调用原型

 +----------------------------------------------------------------------------------------
| //#include <pthread.h>
| //终止线程,并传出线程终止状态的地址。
| //可以被其它线程通过pthread_join获取线程的终止状态
| void pthread_exit(void *rval_ptr);
| void pthread_join(pthread_t thread, void **rval_ptr);
+---------------------------------------------------------------------------------------+

线程运行管理

Windows API声明

 +----------------------------------------------------------------------------------------
| //挂起线程
| DWORD SuspendThread(
| HANDLEhThread
| );
| //恢复执行挂起的线程
| DWORD ResumeThread(
| HANDLEhThread
| );
+---------------------------------------------------------------------------------------+

线程运行函数里,实现pthrea_cond_t,或者接收信号处理。可以实现类似于SuspendThread和ResumeThread的线程管理。

调度优先级

Windows调度原则:CPU总是执行可执行线程中优先级最高的

 即:高优先级的线程会抢占低优先级的线程的资源。

线程共有0-31共32个优先级,31最高,1最低,0为预留给内存清零线程。线程运行的优先级的值

 首先取决于所在进程的优先级类别,
然后是线程对应于进程优先级类别的优先级。

Windows API声明

 +----------------------------------------------------------------------------------------
| // 设置进程的优先级类别
| // 优先级类别dwPriorityClass可以是以下值(优先级从低到高):
| //IDLE_PRIORITY_CLASS
| //BELOW_NORMAL_PRIORITY_CLASS
| //NORMAL_PRIORITY_CLASS
| //ABOVE_NORMAL_PRIORITY_CLASS
| //HIGH_PRIORITY_CLASS
| //REALTIME_PRIORITY_CLASS
| BOOL SetPriorityClass(
| HANDLEhProcess,//进程句柄
| DOWRDdwPriorityClass//优先级类别
| );
| // 设置线程的对就于优先级别的优先级
| // nPriority可以取以下值:
| //THREAD_PRIORITY_ABOVE_NORMAL:线程优先级值比优先级别+1
| //THREAD_PRIORITY_BELOW_NORMAL:线程优先级值比优先级别-1
| //THREAD_PRIORITY_HIGHEST:线程优先级比优先级别+2
| //THREAD_PRIORITY_IDLE:取基本优先级值1或15(REALTIME_PRIORITY_CLASS)
| //THREAD_PRIORITY_LOWEST:线程优先级比优先级别-2
| //THREAD_PRIORITY_TIME_CRITIAL:取基本优先级值15或31(REALTIME_PRIORITY_CLASS0)
| BOOL SetThreadPriority(
| HANDLEhThread,
| intnPriority
| );
+---------------------------------------------------------------------------------------+

+------------priority tables--------------------------------------------------------+
| | Process Priority Class |
| Relative Thread +------+--------------+--------+--------------+-------+----------+
| Priority | IDLE | BELOW NORMAL | NORMAL | ABOVE NORMAL | HIGHT | REALTIME |
+------------------+------+--------------+--------+--------------+-------+----------+
| TIME CRITIAL | 15 | 15 | 15 | 15 | 15 | 31 |
+------------------+------+--------------+--------+--------------+-------+----------+
| HIGHTEST | 6 | 8 | 10 | 12 | 15 | 26 |
+------------------+------+--------------+--------+--------------+-------+----------+
| ABOVE NORMAL | 5 | 7 | 9 | 11 | 14 | 25 |
+------------------+------+--------------+--------+--------------+-------+----------+
| NORMAL | 4 | 6 | 8 | 10 | 13 | 24 |
+------------------+------+--------------+--------+--------------+-------+----------+
| BELOW NORMAL | 3 | 5 | 7 | 9 | 12 | 23 |
+------------------+------+--------------+--------+--------------+-------+----------+
| LOWEST | 2 | 4 | 6 | 8 | 11 | 22 |
+------------------+------+--------------+--------+--------------+-------+----------+
| IDLE | 1 | 1 | 1 | 1 | 1 | 15 |
+------------------+------+--------------+--------+--------------+-------+----------+

Linux中提供三种调度策略,分别是:

 SCHED_FIFO:实时调度,先来先服务调度
SCHED_RR:实时调度,时间片轮转调度
SCHED_OTHER:分时调度
linux一般进程使用分时调度策略。

实时进程(线程)比分时进程(线程)优先调用
实时进程根据实时优先级决定调度权值。
分时进程根据分时优先级(nice值)和时间片(counter)值决定调度权值。

分时优先级(nice值)为-20~19 共40个级别,其中-20 优先级别最高,默认优先级为0。
实时优先级为0~99,99优先级最高,默认为0。

进程和线程在内核中进程和线程都是使用task_struct结构体描述的,在系统调度的应用中并没有区别,因此可以单独为线程或者进程设置调度策略和运行优先级。

Linux 系统调用原型

Linux中提供了多个控制调度的系统调用

用nice改变进程或者线程的分时运行优先级(nice值):

 +----------------------------------------------------------------------------------------
| // #include <unistd.h>
| // 增加优先级的值
| // inc表示优先级增加的值
| //正值表示降低优先级
| //负值表示升高优先级
| // 只有root才能升高优先级
| int nice(int inc);
+---------------------------------------------------------------------------------------+

用setpriority设置运行优先级别:

 +----------------------------------------------------------------------------------------
| //#include <sys/time.h>
| //#include <sysresource.h>
| // 设置进程,进程组,和用户的进程执行优先权
| // which可以为以下值:
| //PRIO_PROCESS为进程设置who 为进程id
| //PRIO_PGRP为进程组设置who 为进程组id
| //PRIO_USER为用户进程设置who 为用户id
| // prio指优先级值,分时调度时:最大为19最小为-20;实时调度时:1~99
| int setpriority(int which, int who, int prio);
+---------------------------------------------------------------------------------------+

用sched_setscheduler设置进程的调度策略和优先级:

 +----------------------------------------------------------------------------------------
| //#include <sched.h>
| int sched_setscheduler(pid_t pid, int policy,
| const struct sched_param *param);
| int sched_getscheduler(pid_t pid);
| struct sched_param {
| ...
| int sched_priority;
| ...
| };
+---------------------------------------------------------------------------------------+

用sched_setparam设置进程的运行优先级:

 +----------------------------------------------------------------------------------------
| //#include <sched.h>
| int sched_setparam(pid_t pid, const struct sched_param *param);
| int sched_getparam(pid_t pid, struct sched_param *param);
| struct sched_param {
| ...
| int sched_priority;
| ...
| };
+---------------------------------------------------------------------------------------+

用pthread_setschedparam设置线程的调度策略和优先级:

 +----------------------------------------------------------------------------------------
| //#include <pthread.h>
| //等价于分别是用pthread_setschedpolicy和pthread_setschedprio设置调度策略和优先级:
| int pthread_getschedparam(pthread_t thread, int *restrict policy,
| struct sched_param *restrict param);
| int pthread_setschedparam(pthread_t thread, int policy,
| const struct sched_param *param);
+---------------------------------------------------------------------------------------+

用pthread_attr_setschedparam通过更改线程属性改变线程的调度策略和优先级:

 +----------------------------------------------------------------------------------------
| //#include <pthread.h>
| int pthread_attr_getschedparam(const pthread_attr_t *restrict attr,
| struct sched_param *restrict param);
| int pthread_attr_setschedparam(pthread_attr_t *restrict attr,
| const struct sched_param *restrict param);
| struct sched_param {
| ...
| int sched_priority;
| ...
| };
+---------------------------------------------------------------------------------------+
原创粉丝点击