代码如下:
#include "vxworks.h"
#include "msgQLib.h"
#include "taskLib.h" /*to use task the program should include taskLib.h */
#include "timers.h" /*to use the time function*/
#include "string.h"
#include "semLib.h" /*to use semphore the program only need inlude semLib.h*/
#include "stdio.h"
SEM_ID semId; /*ID of the mutual semphore*/
int taskSemTakeId;
int taskSemTake1Id; /*Id of the task of semTake 1*/
int taskSemTake2Id;
int taskSemTake3Id;
int taskSemGive1Id; /*Id of the task of semGive 1*/
int taskSemGive2Id;
int taskSemCreateId;
/*declaration of the task function*/
LOCAL void taskSemTake1(); /*the high priority task*/
LOCAL void taskSemTake2(); /*the high priority task*/
LOCAL void taskSemTake3(); /*the high priority task*/
LOCAL void taskSemGive1(); /*the low priority task*/
LOCAL void taskSemGive2(); /*the low priority task*/
LOCAL void taskSemCreate(); /*the low priority task*/
int createTsemTake(int iteration);
int createTsemGive(int iteration);
int createTsemCreate();
LOCAL int takeSem();
LOCAL void taskSemCreate()
{
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
semId=semMCreate(SEM_Q_PRIORITY); /*Create the semphore*/
if(semId==NULL)
{
printf("Can't create a mutual semphore!\n");
/*There should be some code here to deal with the error and exit*/
}/*if*/
clock_gettime(CLOCK_REALTIME,(timespec*)¤t_time);
printf("In time:%ld",current_time.tv_nsec);
printf("success to create the mutual semphore!\n");
}/*taskSemCreate*/
LOCAL void taskSemTake1()
{
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("@@In time:%ld",current_time.tv_nsec);
printf("The mutual semphore will be taken now!\n");
semTake(semId,5000); /*take the mutual semphore*/
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("##In time:%ld",current_time.tv_nsec);
printf("The mutual semphore was taken!\n");
}/*taskSemTake1*/
LOCAL void taskSemTake2()
{
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("@@In time:%ld",current_time.tv_nsec);
printf("The mutual semphore will be taken now!\n");
semTake(semId,5000); /*take the mutual semphore*/
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("##In time:%ld",current_time.tv_nsec);
printf("The mutual semphore was taken!\n");
}/*taskSemTake1*/
LOCAL void taskSemTake3()
{
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("@@In time:%ld",current_time.tv_nsec);
printf("The mutual semphore will be taken now!\n");
semTake(semId,5000); /*take the mutual semphore*/
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("##In time:%ld",current_time.tv_nsec);
printf("The mutual semphore was taken!\n");
}/*taskSemTake1*/
LOCAL void taskSemGive1()
{
STATUS ret;
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
semGive(semId); /*take the mutual semphore*/
ret=semGive(semId); /*take the mutual semphore*/
if(ret==ERROR)
{
printf("Can't release the semphore");
}
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("##In time:%ld",current_time.tv_nsec);
printf("The mutual semphore has been given just now!\n");
}/*taskSemTake1*/
LOCAL void taskSemGive2()
{
STATUS ret;
struct Tag_timespec
{
time_t tv_sec; /*second*/
long tv_nsec; /**/
}current_time;
ret=semGive(semId); /*take the mutual semphore*/
if(ret==ERROR)
{
printf("Can't release the semphore");
}
clock_gettime(CLOCK_REALTIME,(timespec*) &(current_time));
printf("##In time:%ld",current_time.tv_nsec);
printf("The mutual semphore has been given just now!\n");
}/*taskSemTake1*/
int createTsemCreate()
{
taskSemCreateId=taskSpawn("tCreateSem",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemCreate,0,0,0,0,0,0,0,0,0,0);
if(taskSemCreateId==ERROR)
{
printf("ERROR occurs in creating taskSemCreate!!!!!\n");
return 0;
}
return 1;
}
int createTsemTake(int iteration)
{
if(iteration==1)
{
taskSemTake1Id=taskSpawn("tsemTake",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemTake1,0,0,0,0,0,0,0,0,0,0);
if(taskSemTake1Id==ERROR)
{
printf("ERROR occurs in creating taskSemTake1!!!!!\n");
return 0;
}
return 1;
}
else if(iteration==2)
{
taskSemTake2Id=taskSpawn("tsemTake",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemTake2,0,0,0,0,0,0,0,0,0,0);
if(taskSemTake2Id==ERROR)
{
printf("ERROR occurs in creating taskSemTake2!!!!!\n");
return 0;
}
return 1;
}
else if(iteration==3)
{
taskSemTake3Id=taskSpawn("tSemTake",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemTake3,0,0,0,0,0,0,0,0,0,0);
if(taskSemTake2Id==ERROR)
{
printf("ERROR occurs in creating taskSemTake3!!!!!\n");
return 0;
}
return 1;
}
else
{
printf("The parameter is error!!\n");
return 0;
}
}
int createTsemGive(int iteration)
{
if(iteration==1)
{
taskSemGive1Id=taskSpawn("tSemGive",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemGive1,0,0,0,0,0,0,0,0,0,0);
if(taskSemGive1Id==ERROR)
{
printf("ERROR occurs in creating taskSemGive1!!!!!\n");
return 0;
}
return 1;
}
else if(iteration==2)
{
taskSemGive2Id=taskSpawn("tsemGive",100,VX_SUPERVISOR_MODE,4000,(FUNCPTR)taskSemGive2,0,0,0,0,0,0,0,0,0,0);
if(taskSemGive2Id==ERROR)
{
printf("ERROR occurs in creating taskSemGive!!!!!\n");
return 0;
}
return 1;
}
else
{
printf("The parameter is error!!\n");
return 0;
}
}
[align=right][color=#000066][此贴子已经被作者于2004-7-6 11:12:42编辑过][/color][/align]
整个程序的代码是为了测试信号量而设置的一个例子,当时图方便没有把那个数据类型的定义放在外面,导致整个程序代码过长,[em04],下面我把整个的思路说一下:
一、任务的功能:
1、taskSemCreate(),这个任务是用来创建mutex信号量的
2、taskSemTake1(),taskSemTake2(),taskSemTake3()这是三个完全一样的任务,都是用来获取信号量的
3、taskSemGive1(),taskSemGive2()是两个完全一样的任务用来释放信号量的 二、函数的功能
4、函数int createTsemCreate()是用来启动taskSemCreate任务从而实际上完成信号量的创建
5、int createTsemTake(int iteration),用来启动taskSemTake1或者taskSemTake2或者taskSemTake3,去获取信号量
6、createTsemGive,用来启动taskSemGive1或者taskSemGive2从而可以释放信号量 三、执行流程
1、我先在shell中调用createTsemCreate,从而启动任务tasksemCreate创立mutex信号量
2、然后用createTsemTake(1);和createTsemTake(2);分别启动任务tasksemtake1和tasksemTake2去获取信号量。 按说,taskTsemtake2应该会被阻塞(pended),但是我用“i”命令查看的时候,发现其并没有被阻塞,不知这是什么原因?
[align=right][color=#000066][此贴子已经被作者于2004-7-6 11:16:15编辑过][/color][/align]
1、taskSemCreate(),这个任务是用来创建mutex信号量的
2、taskSemTake1(),taskSemTake2(),taskSemTake3()这是三个完全一样的任务,都是用来获取信号量的
3、taskSemGive1(),taskSemGive2()是两个完全一样的任务用来释放信号量的 二、函数的功能
4、函数int createTsemCreate()是用来启动taskSemCreate任务从而实际上完成信号量的创建
5、int createTsemTake(int iteration),用来启动taskSemTake1或者taskSemTake2或者taskSemTake3,去获取信号量
6、createTsemGive,用来启动taskSemGive1或者taskSemGive2从而可以释放信号量 三、执行流程
1、我先在shell中调用createTsemCreate,从而启动任务tasksemCreate创立mutex信号量
2、然后用createTsemTake(1);和createTsemTake(2);分别启动任务tasksemtake1和tasksemTake2去获取信号量。 按说,taskTsemtake2应该会被阻塞(pended),但是我用“i”命令查看的时候,发现其并没有被阻塞,不知这是什么原因?
[align=right][color=#000066][此贴子已经被作者于2004-7-6 11:16:15编辑过][/color][/align]
3楼
注意Mutex 信号量,它仅能由提取它(即调用semTake())的任务释放。
你可用二进制(互斥)信号量试一试:
semId = semBCreate(SEM_Q_PRIORITY, full);
4楼
不好意思,写错了,应该是:
semId = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
123456,非常感谢你的指点。其实我设置这个例子本来就是想试一下binary信号量和mutex(或者叫mutual)信号量的区别。结果没想到碰到了其他的问题。我对信号量的机制的确是有很多不明白的地方,还要请你继续指点:
1、我按照你说的第二次回帖中的说法,在taskTsemtake1任务中最后一句加了taskDelay之后的确可以实现阻塞了,只要在taskTsemtake1仍处于生存状态时启动任务taskTsemtake2,则第二个任务就会阻塞,阻塞以后,如果taskdelay设置的时间短,即使taskTsemtake1自杀了,任务taskTsemtake2仍会处于阻塞状态。但是如果在任务taskTsemtake1自杀之后再启动任务taskTsemtake2,则其不会被阻塞。这是什么原因呢?
难道说,如果一个任务自杀了,那么它对信号量的占用状态也就结束了?但如果是这样,那么应该在taskTsemtake1自杀之后,taskTsemtake2就应该自动解除阻塞呀。
以下是引用123456在2004-7-7 16:08:00的发言:
有一个概念你要澄清,从程序上来说,互斥信号量只能由take它的task来give,所以程序员要格守该任务未give它之前不会被杀死(这就是我前面所说taskSafe的原因)。故你说的“一个任务自杀了,那么它对信号量的占用状态也就结束了?”这个问题的前提本身就是错误的。同时你顶楼的贴想起一个任务take一个互斥信号量,然后指望另起一个任务来give它是错误的。从编程细节上讲: 你应把下面一句: semId=semMCreate(SEM_Q_PRIORITY); /*Create the semphore*/ 改为: semId=semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE); /*Create the semphore*/ 试一试,我觉得应该同样可以达到阻塞task2的结果。
插一句:“从程序上来说,互斥信号量只能由take它的task来give” 有这样的规定?事实上,在我实际编码过程中,在一个task 里take 的 sem 完全 可以在另一个task 中give 的,而且运行良好...
有一个概念你要澄清,从程序上来说,互斥信号量只能由take它的task来give,所以程序员要格守该任务未give它之前不会被杀死(这就是我前面所说taskSafe的原因)。故你说的“一个任务自杀了,那么它对信号量的占用状态也就结束了?”这个问题的前提本身就是错误的。同时你顶楼的贴想起一个任务take一个互斥信号量,然后指望另起一个任务来give它是错误的。从编程细节上讲: 你应把下面一句: semId=semMCreate(SEM_Q_PRIORITY); /*Create the semphore*/ 改为: semId=semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE); /*Create the semphore*/ 试一试,我觉得应该同样可以达到阻塞task2的结果。
插一句:“从程序上来说,互斥信号量只能由take它的task来give” 有这样的规定?事实上,在我实际编码过程中,在一个task 里take 的 sem 完全 可以在另一个task 中give 的,而且运行良好...
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |