POSIX标准总体分析 执行调度 消息传递 调度参数 进程调度函数 关闭消息队列 得到消息队列参数 设置调度参数 时钟和定时器 时钟和定时器函数 消息传递函数 打开消息队列 设置消息队列参数
粉丝不过w
调度参数
一个调度参数结构 sched_param 包括了调度策略所支持的执行者所需要的调度参数,它在头文件<sched.h>中定义
执行者可根据规对该结构进行扩展
调度策略
调度术语是从概念模型上定义的,它包含了一组进程列表。这个模型只讨论了可运行进程的处理器调度,但是它注重了在其他资源考虑到处理器调度策略的情况下,增强了实时操作的可预见性
在这里,概念上讲是一个进程列表一个策略。调度策略的目的就是对这一组列表定义允许的操作(如,在进程列表之中和之间移动进程)
每一个进程应由相关的调度策略和优先级,于每一个策略相关的是一个优先级范围
SCHED_FIFO
该策略是一种先进先出的调度策略。如 正在执行的进程是被抢占的进程,则他应该在进程列表头;如 一个锁定的进程变成可执 行 进 程 , 它 就 进 入 进 程 列 表 尾
当 执 行 进 程 调 用sched_setscheduler(),则函数中确定的进程被改为指定的策略
当执行进程调用 sced_setparam(),进程的优先级根据参数 param 被修改,如果改进程是正在执行和可执行,则它将进入进程列表尾
当正在执行的进程调用 seced_yield(),进程进入列表尾
SCHED_RR
该策略与上面的策略不同的是,如果执行中检测到进程的执行时间已经到达或超过了 sched_rr_get_interval()所返回的时间片,进程就进入列表尾并且进程列表头移动一个进程进入执行状态
进程调度函数
设置调度参数
#include <sched.h>
//pid 指明了进程,param 指向了 sched_param 结构,该结构设定了进程的调度参数
// 如 pid = 0,调度参数为调用进程设定
// 如 pid 指定的进程的优先级高于正在指向的进程并且该进程可执行,则抢占现在正在运行的进程
//如 当前的策略不是前面将的三种方式,则由执行者定义
int sched_setparam(pid_t pid, const sched_param *param);
取得调度参数
#include <sched.h>
//返回调度参数,如 一个 pid 进程退出并且调用进程允许,则 ID 等于 pid 的进程返回其调用参数
//如 pid = 0,则返回调用进程的调度参数
int sched_getparam(pid_t pid,struct sched_param *param);
设置调度策略和调度参数
#include <sched.h>
//设置进程的调度策略和调度参数,pid :进程,policy 指明策略
//param 指向的 sched_param 结构指明了调度参数
//执行者可要求请求进程能允许设定自己或其他进程的调度参数
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
取得调度策略
#include <sched.h>
//返回 pid 进程的调度策略,其返回值在头文件<sched.h>中定义
int sched_getcheduler(pid_t pid);
放弃处理器
#include <sched.h>
//迫使正在执行进程放弃处理器直到重新进入进程列表头
int sched_yield(void);
获得调度参数范围
#include <sched.h>
//返回 policy 调度策略相应的最大
int sched_get_priority_max(int policy);
//最小值
int sched_get_priority_min(int policy);
// 更新 interval 参数引用的 timespec 结构,包含了当前进程执行的时间限制
int sched_rr_get_interval(pid_t pid, struct timespec *interval);
时钟和定时器
时钟和定时器的数据定义
头文件<time.h>定义了时间设备用到的类型和主要常量
时间值的规格结构
一个时间值结构 timespec 确定了单一时间值并且包括了以下值:
成员类型 | 成员名 | 描述 |
time_t | tv_sec | seconds |
long | tv_nsec | nanosenconds |
执行者可对他做扩展, tv_nsed 成员要大于等于零时才可用
时间值结构 itimerspec 确定了一个初始化的定时器和各进程定时器函数用到的重复间隔
结构包括:
成员类型 | 成员名 | 描述 |
struct timespec | it_interval | timer period |
struct timespec | it_value | timer expiration |
定时器活动唤醒控制块
为了支持实时信号扩展功能,各进程定时器被创建通过 排列实时扩展信号 来通知定时器超时的进程
sigevent 结构在头文件<signal.h>中定义,用来创建一个这样的定时器
时钟和定时器函数
时钟
#include <time.h>
//设置特定时钟, clock_id, 到 tp 指定的值
int slock_settime(clockid_t clock_id, const struct timespec *tp);
//返回当前的 tp 值, 即时钟, clock_id
int clock_gettime(clockid_t clock_id, struct timespec *tp);
/*
* 得到时钟的决定值, 该值由执行者定义而不由进程设定
* res:
* != 空,该值被存储在 res 指向的地方
* = 空,时钟决定值不被返回
*/
int clock_getres(clockid_t clock_id, struct timespec *res);
创建一个总进程定时器
#include <stgnal.h>
#include <time.h>
/*创建一个总进程定时器,用来指明时钟,clock_id,作为计时基础
*指向的地方返回一个 timer_t 类型的定时器 ID,该 ID 在调用进程中必须是唯一的直到定时器被删除
* evp != 空,则指向一个 sigevent 结构,定义了定时器超时时出现的异步通知
int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid);
删除一个总进程定时器函数原型
#include <time.h>
/*
*删除一个指定的定时器
*timerid,该定时器是在以前的 timer_create()中创建的
*/
int timer_delete(time_t timerid);
总进程定时器
#include <time.h>
//设置时间直到下一个 timerid 指定的定时器终止
int timer_settime(timer_t timerid,
int flags,
const struct itimerspec *value,
struct itimerspec *ovalue);
高度睡眠
#include <time.h>
//使当前执行的进程挂起直到参数 rptp 指定的时间间隔到达或者 信号被送到调用进程并且其行为就是唤醒信号跟踪功能或者使终止进程
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
消息传递
消息队列的数据定义
数据结构
头文件< mqueue.h>定义
mqd_t :用于消息队列描述符
struct sigevent
mq_attr:用来设定消息队列参数
struct sigevent 结构包含了至少以下的成员:
类型 | 成员名 | 描述 |
long | mq_flags | 消息队列标志 |
long | mq_maxmsg | 最大消息数 |
long | mq_msgsize | 消息的最大长度 |
long | mq_curmsgs | 当前排列的消息数 |
消息传递函数
打开消息队列
#include <mqueue.h>
/*
*在进程和消息队列之间建立连接
*创建了一个消息队列描述符指向消息队列
*oflag: 请求对消息队列发送或接收所需信息
*如 调用进程承认对相应保护文件的读写请求,则对接收或发送消息的请求允许被通过
*/
mqd_t mq_open(const char *name, int oflag, ...);
关闭一个消息队列
#include <mqueue.h>
/*
*撤销消息队列描述符(mqdes)和消息队列之间的关系
*如 进程成功的配属了 mqdes 表示的消息队列通知请求,则这个配属关系被撤销
*该消息队列可用于其他进程来配属通知
*/
int mq_close(mqd_t mqdes);
移去一个消息队列
#include <mqueue.h>
/*
*移去路径名 name 指向的消息队列
*如 该调用成功, 且 flag 没有设为 O_CREATE,则 mq_open()对于同一个 name 将会失败
*所有对该队列的引用撤销后,该队列才能被关闭
*该函数调用不会被阻塞指定所有的引用被关闭
*/
int mq_unlink(const char *name);
发送一个消息到消息队列
#include <mqueue.h>
/*
*该函数添加参数 msg_ptr 指向的消息到 mqdes 指定的消息队列中去
*msg_len:消息长度,以字节为单位,该参数应小于等于消息队列的 mq_msgsize参数,否则调用失败
*如 消息队列没有满,则插入消息到消息队列的指定位置,这个位置由 msg_prio 参数指定
*msg_prio 大者先插入队列, msg_prio 的值应小于等于{ MQ_PRIO_MAX }
*如 消息已满并且 O_NONBLOCK 没有设定,该函数阻塞一直到空间可用或者 mq_send()被信号中断
*如 空间可用时,多于一个进程在等待发送则按优先级,等待最久的进程先发送它的信息
*如 O_NONBLOCK 被设定,并且队列已满,则函数返回 error
*/
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t mag_len, unsigned int msg_prio);
从消息队列接受一条消息
#include <mqueue.h>
/*
*接受 mqdes 确定的消息队列中最久优先级最高的消息,对参数值的限制同上
*所选消息从队列移出,复制到 msa_ptr 指向的缓冲区
*如 msg_prio != 空,则指定消息被存储在 msa_prio 所引用的地方
*如 消息队列 = 空,且 O_NONBLODK 没有设定,该函数阻塞直到消息排列入队列中或者该函数被信号中断
*当有多个进程在消息到达队列后请求接受,则优先级原则与上相同
*/
ssize_t mq_receive(mqd_t mqdes,
char *msg_ptr,
size_t msg_len,
unsigned int *msg_prio);
通知一个进程队列中的一条信息可用
#include <mqueue.h>
/*
*如 notification != 空,函数记录下调用进程被通知空的消息队列中有一条消息到来
*当消息队列从空到非空时,一条通知消息将发送到进程中
* 在任一时刻,只有一个通知消息被一个消息队列记录
* 如 notifiction =空,且进程当前被指定的队列记录,则已存在的记录被移去
*/
int mq_notify(mqd_t mqdes, const struct sigevent *notification);
设置消息队列参数
#include <mqueue.h>
/*
*用来设置与 mqdes 指定的消息队列相关的参数
*mq_attr 结构中的 mq_maxmsg,mq_magsize,mq_curmsgs成员被 mq_setattr()忽略
*如 omqstat 为非空,则该函数被存储,由 omqstat 指明存储位置
*/
int mq_setattr(mqd_t mqdes,
const struct mq_attr *mqstat,
struct mq_attr *omqstat);
得到消息队列参数
#include <mqueue.h>
//用来取得状态信息和与 mqdes 消息队列相关的参数
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
由于笔者水平有限,难免有些疏忽的地方,愿大家指出,谢谢!!!