ostasksempost可以多个任务给一个任务发吗

ostasksempost可以多个任务给一个任务发吗,第1张

1、首先需要知道,μC/OS-II中创建任务的函数有两个: OSTaskCreate()和OSTaskCreateExt()

(1)OSTaskCreate() //创建普通任务

由于重点在下面的创建扩展任务函数,故本函数就不多说了!确实,要想实现检测目标任务栈实际使用情况的功能,是不能使用这个函数来创建目标任务的,必须使用OSTaskCreateExt() 。

(2)OSTaskCreateExt() //创建扩展任务

函数接口原型为:

#if OS_TASK_CREATE_EXT_EN >0

INT8U OSTaskCreateExt

(

void (*task)(void *pd), //建立扩展任务(任务代码指针

void *pdata, //传递参数指针

OS_STK *ptos, //分配任务堆栈栈顶指针

INT8U prio, //分配任务优先级

INT16U id, //(未来的)优先级标识(与优先级相同)

OS_STK *pbos, //分配任务堆栈栈底指针

INT32U stk_size, //指定堆栈的容量(检验用)

void *pext, //指向用户附加的数据域的指针

INT16U opt //建立任务设定选项

)

#endif

2、其次需要知道μC/OS-II中有这么个函数:OSTaskStkChk()

不错,检测任务堆栈实际使用情况正是用的这个函数,下面来本函数的接口原型:

INT8U OSTaskStkChk

(

INT8U prio, //待测任务的优先级

OS_STK_DATA *pdata //指向一个类型为OS_STK_DATA的结构体

)

3、再次需要知道一个结构体:

#if OS_TASK_CREATE_EXT_EN >0

typedef struct

{

INT32U OSFree//堆栈中未使用的字节数

INT32U OSUsed//堆栈中已使用的字节数

} OS_STK_DATA

#endif

参数: prio 为指定要获取堆栈信息的任务优先级,也可以指定参数OS_PRIO_SELF,获取调用任务本身的

信息。

pdata 指向一个类型为OS_STK_DATA的数据结构,其中包含如下信息:

INT32U OSFree// 堆栈中未使用的字节数

INT32U OSUsed// 堆栈中已使用的字节数

(1)Posix标准中有有名信号灯和无名信号灯之分,对于有名信号灯,可以用sem_open来创建,其prototype是:

sem_t *sem_open(const char *name, int oflag)//打开已有的信号灯

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned value)//一般是创建信号灯。

期中name是信号灯的名字, oflag是0, O_CREAT 或者 O_CREAT | O_EXCL, 如果指定O_CREAT, 那么mode和value对应创建该信号的模式和初始值。 如果指定了O_EXCL, 而且该信号灯已经在系统中存在,那调用会出错返回SEM_FAILED常量。 对于Linux内核来说,有名信号灯是很晚才加入内核中的,创建或是打开有名信号时候,应该指定”/semname“名字,对应的信号灯创建在/dev/shm目录下,名字是/dev/shm/sem.semname. BTW, 用gcc/g++编译实用信号灯功能的程序时候,应该引用librt库,(e.g., g++ -lrt sem.cpp). 关闭已打开的信号灯,用sem_close(sem_t *sem). 关闭信号灯并不意味着系统会删除它,要删除一个信号灯,需要调用sem_unlink(sem_t *sem)。 有名信号灯一般是为了进程之间同步实用的。 无名信号灯,一般是为一个进程内的不同线程之间同步使用的。 创建无名信号灯的方法如下:

sem_t sem

sem_init(&sem, int shared, unsigned int value)//初始化信号灯。

......

sem_destroy(&sem)//清除信号灯。

(2)信号灯的使用和状态。

信号灯一般用来描述不同线程所共享的公共资源的数量,每一个信号灯都有一个叫做信号量的非负整数与之相连;信号量一般代表公共资源的数目,比如空闲列表中的缓冲区数目,视频中读入帧的数目,等等。对于一个线程可以用sem_wait, sem_post函数来改变一个信号灯的信号量。

sem_wait(sem_t &sem)

sem_wait的语义如下:

{

while(信号量==0)

等待; //此处线程被挂起,等待其他线程调用sem_post唤醒之。

信号量减1;

}

注意:测试信号量是否为零,和减一的操作是原子的,也就是说期间不会发生线程切换。

与sem_wait对应的调用是sem_post,语义如下:

{

信号量加1;

唤醒等待该信号量的线程;//调用sem_wait并等待的线程。

}

该操作也是原子的。

信号灯的状态可以用sem_getvalue来查看。一般来说sem_wait和sem_post的调用不必在同一个线程内成对出现(象mutex那样,lock/unlock要配对出现)。 一般的情形是这样的,一个线程等待资源可用,调用sem_wait, 另外一个线程生成资源,然后调用sem_post,唤醒等待该资源的线程。因为信号灯所描述的是线程间公共资源,使用的时候一般和mutex一起使用,mutex保证访问公共资源的线程排他性,信号灯表示资源的可用性。

sem_init:初始化信号量sem_t,初始化的时候可以指定信号量的初始值,以及是否可以在多进程间共享。

sem_wait:一直阻塞等待直到信号量>0。

sem_timedwait:阻塞等待若干时间直到信号量>0。

sem_post:使信号量加1。

sem_destroy:释放信号量。和sem_init对应。 答案补充 关于各函数的具体参数请用man查看,如man sem_init可查看该函数的帮助


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/78205.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-03
下一篇2023-03-03

发表评论

登录后才能评论

评论列表(0条)

    保存