|
本帖最后由 wangpengcheng 于 2014-9-9 14:05 编辑
前几天回老家,坐火车,也怪我自己,上车之前吧,有点想上厕所的冲动,但是又怕到时候挤不上车,就忍着,反正车上有厕所,上车再解决吧!结果上车后,安排好座位,行李,直奔厕所,这回郁闷了,厕所关着门,有人占用!唉,算了再憋回吧,但还得回去看行李。过了回再来看,还是有人,再回去看住行李。如此来回几趟!突然我发现列车的前后都有厕所是否为空的指示灯啊,绿色的时候说明没有人,红色的时候说明有人,于是我就不用再来回跑了,盯着灯看,一旦变绿了,赶紧冲过去解决了问题,这个爽啊!
呵呵,同学们,后来我想了,这灯是什么呢?这不就是互斥量吗?共同资源,有一方占用,那么可将占用互斥量,其它想用,不好意思,不能用,想用你得等我将互斥量释放出来,这不跟列车上厕所的灯一样一样的吗?
好吧,我想现在我知道什么是互斥量了!下面我就刚才的例子做用代码描述一下吧,虽然例子有点不文明,但比较形象!
首先,我建一个旅客属性的结构体:
- typedef struct _PassengerAttribute
- {
- char Name; //旅客名称
- char *Food; //旅客自备的食物
- char *Drinks; //旅客自备的饮料
- uint32_t WaitTime; //旅客吃完喝完要等这么长时间才去厕所
- uint32_t UseToiletTime; //旅客在厕所里也需要这时间进行解决啊
- }PassengerAttribute, *PassengerAttribute_PTR;
复制代码
好吧,现在我们看看旅客A跟B都带了什么!
假如旅客A家里比较有钱,带的是汉堡、可乐,但是它消化系统不好,平均需要1S就得占用一次厕所,一次占用2S钟时间。
- PassengerAttribute PassengerA = { 'A', "Hamburger", "Cola", 1000, 2000 };
复制代码
旅客B家境稍贫寒一点,带的是馒头跟凉白开,但旅客B由于经常劳动,身体不错,他平均1.5S去一次厕所,而且时间很快,0.5S就解决了!
- PassengerAttribute PassengerB = { 'B', "Steamed buns", "Water", 1500, 500 };
复制代码
现在旅客已经准备好了,我开始准备列车了,准备列车需要两个元素,一个是厕所的互斥量:
- MUTEX_STRUCT ToiletMutex;
复制代码
另一个就是一个过程,过程需要先初始化互斥量,然后请旅客上车,那我就用一个初始化任务来解决吧:
- void MainTask(uint32_t para)
- {
- MUTEX_ATTR_STRUCT mutexattr; //互斥量属性,这个去mutex.h文件里找吧,跟前面两节一样,它一样有好几个属性,同样我也没用几个,呵呵,我人懒了!
- /* Initialize mutex attributes: */
- if (_mutatr_init(&mutexattr) != MQX_OK) { //初始化互斥量属性
- printf("Initializing mutex attributes failed.\n");
- _mqx_exit(0);
- }
- /* Initialize the mutex: */
- if (_mutex_init(&ToiletMutex, &mutexattr) != MQX_OK) { //初始化互斥量
- printf("Initializing print mutex failed.\n");
- _mqx_exit(0);
- }
- /* Create the print tasks */
- _task_create(0, PASG_TASK, (uint32_t)&PassengerA); //旅客A上车了
- _task_create(0, PASG_TASK, (uint32_t)&PassengerB); //旅客B上车了
- }
复制代码
从上面的任务中,可以看出,其实我创建了两个同样的任务,只是输入参数不同了,为什么呢?因为旅客的行为都是一样的,只是他们的属性不一样罢了,我这么做的话,有个好处,可以少写一些代码!
下面旅客上车后就开始了他们的动作跟行为:
- //吃东西
- void Eat(PassengerAttribute_PTR Passenger)
- {
- printf("Passenger %c eat %s!\r\n", Passenger->Name, Passenger->Food);
- }
- //喝饮料
- void Drink(PassengerAttribute_PTR Passenger)
- {
- printf("Passenger %c drink %s!\r\n", Passenger->Name, Passenger->Drinks);
- }
- //用厕所
- void UseTheToilet(PassengerAttribute_PTR Passenger)
- {
- if (_mutex_lock(&ToiletMutex) != MQX_OK) { //进厕所后先锁门
- printf("Mutex lock failed.\n");
- _mqx_exit(0);
- }
- printf("Passenger %c use the toilet %d time!\r\n", Passenger->Name, Passenger->UseToiletTime);
- _time_delay(Passenger->UseToiletTime); //占坑时间
- _mutex_unlock(&ToiletMutex); //出厕所后把门打开
- printf("Passenger %c use the toilet end!\r\n", Passenger->Name);
- }
- void PassengerTask(uint32_t para)
- {
- PassengerAttribute_PTR Passenger = (PassengerAttribute_PTR)para;
- while(1)
- {
- Eat(Passenger); //吃东西
- Drink(Passenger); //喝饮料
- _time_delay(Passenger->WaitTime); //等待
- UseTheToilet(Passenger); //上厕所
- }
- }
复制代码
呵呵,看到了吧?进了厕所要锁门,出了厕所打门打开,方便后面的人继续用啊!
现在我们把所需要的元素都定义好了,就可以开始了!
好吧,我忘记铁路局了,铁路局还没定义呢,当然铁路局就是我们的任务列表, 这个相信已经不用我再说了吧?
- const TASK_TEMPLATE_STRUCT MQX_template_list[] =
- {
- /* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice */
- { MAIN_TASK, MainTask, 1500, 8, "main", MQX_AUTO_START_TASK, 0, 0 },
- { PASG_TASK, PassengerTask, 1500, 9, "pasg", MQX_USER_TASK , 0, 0},
- { 0 }
- };
复制代码
OK,现在一切准备就绪,让我们的列车开始运行吧:
从结果中,我们可以看出,不管是A还是B,在占用厕所的时候,别人就算着急了,也上不了!唉,下次我上车前得先解决了再上,教训啊
什么?还有API没说,好吧,呵呵,所有API函数以及常量都在mutex.h文件中,一般人我不告诉他!
最后照例是源码:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|