这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » mutex信号量,谁能看看这样为什么不阻塞?

共11条 1/2 1 2 跳转至

mutex信号量,谁能看看这样为什么不阻塞?

菜鸟
2004-07-06 16:37:54     打赏
代码如下:
#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]



关键词: mutex     信号     谁能     看看     这样     为什么     阻塞         

菜鸟
2004-07-06 16:55:00     打赏
2楼
整个程序的代码是为了测试信号量而设置的一个例子,当时图方便没有把那个数据类型的定义放在外面,导致整个程序代码过长,[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]

菜鸟
2004-07-06 17:07:00     打赏
3楼
注意Mutex 信号量,它仅能由提取它(即调用semTake())的任务释放。 你可用二进制(互斥)信号量试一试: semId = semBCreate(SEM_Q_PRIORITY, full);

菜鸟
2004-07-06 17:14:00     打赏
4楼
不好意思,写错了,应该是: semId = semBCreate(SEM_Q_PRIORITY, SEM_FULL);

菜鸟
2004-07-06 19:11:00     打赏
5楼
binary信号量我试过了是可以实现阻塞的,我现在不明白的是为什么Mutex信号量就不阻塞了。由于taskSemTake1任务获取了信号量并且没有释放,当taskSemTake2任务去获取mutex信号量时,由于信号量被taskSemTake1任务占用,按说taskSemTake2任务应该会被阻塞的。

菜鸟
2004-07-07 00:40:00     打赏
6楼
我试了一下,如果超时时间限制换成WAIT_FOREVER能阻塞,但是如果换成一个具体的的时间,甚至是100000都不行。应该不是我用“i”命令查看不及时的原因,因为我同时用windview查看了,根本就没有出现阻塞。不知道到底是怎么回事。 [align=right][color=#000066][此贴子已经被作者于2004-7-6 19:51:53编辑过][/color][/align]

菜鸟
2004-07-07 06:19:00     打赏
7楼
123456,非常感谢你的指点。其实我设置这个例子本来就是想试一下binary信号量和mutex(或者叫mutual)信号量的区别。结果没想到碰到了其他的问题。我对信号量的机制的确是有很多不明白的地方,还要请你继续指点: 1、我按照你说的第二次回帖中的说法,在taskTsemtake1任务中最后一句加了taskDelay之后的确可以实现阻塞了,只要在taskTsemtake1仍处于生存状态时启动任务taskTsemtake2,则第二个任务就会阻塞,阻塞以后,如果taskdelay设置的时间短,即使taskTsemtake1自杀了,任务taskTsemtake2仍会处于阻塞状态。但是如果在任务taskTsemtake1自杀之后再启动任务taskTsemtake2,则其不会被阻塞。这是什么原因呢? 难道说,如果一个任务自杀了,那么它对信号量的占用状态也就结束了?但如果是这样,那么应该在taskTsemtake1自杀之后,taskTsemtake2就应该自动解除阻塞呀。

菜鸟
2004-07-08 00:37:00     打赏
8楼
谢谢你。我编这段程序的目的就是验证感受一下mutex信号量只能由take它的任务来释放这一特性,所以故意把give单独放在一个任务中,从而试一下如果另有一个任务试图释放该信号量会出现什么情况。对mutex信号量我还是有一些机制搞不清楚,可以qq交流吗,我的qq是249423271。 [align=right][color=#000066][此贴子已经被作者于2004-7-7 21:07:39编辑过][/color][/align]

菜鸟
2004-07-13 23:55:00     打赏
9楼
我的msn是qd_hjx@hotmail.com,谢谢您的指点。可惜我最近上网不方便,不能向您请教,遗憾!

菜鸟
2004-08-05 18:48:00     打赏
10楼
以下是引用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 的,而且运行良好...

共11条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]