多任务通信概要.doc
8页嵌入式系统实验报告实验2 多任务通信一、 实验目的 1、熟悉VxWorks进程间通信机制,并通过实验了解资源冲突的原因和解决方法 二、 实验要求1、设计两个任务tHigh和tLow,分别访问两个共享资源,达到下图的死锁效果,死锁效果,并解决该死锁问题,用windview分析三、 实验原理1、VxWorks的信号量(1)二进制信号量:最快和常用的信号量,提供阻塞方式,用于实现同步或互斥2)互斥信号量:用于实现互斥问题的特殊的二进制信号量,解决具有互斥、优先级继承、删除安全和递归等情况3)计数信号量:类似于二进制信号量,记录信号量被释放的次数适合于一个资源的多个实例需要保护的情况2、互斥信号量的创建、获取和释放 (1)semMCreate( ):分配并初始化一个互斥信号量,函数原型为:SEM_ID semBCreate ( int options, /*信号量选项*/ SEM_B_STATE initialState /*信号量初始化状态值*/ ); (2)semTake( ):占有一个信号量,函数原型为:STATUS semTake ( SEM_ID semId /*所要得到的信号量ID号*/ int timeout /*等待时间*/ );(3)semGive( ):释放一个信号量,函数原型为:STATUS semGive ( SEM_ID semId /*所给出的信号量ID号*/ );(4)创建任务int taskSpawn( name, priority, options, stackSize, entryPt, arg1,…,arg10)Name任务名,如果是NULL系统就给一个默认的名字;Priority 任务优先级,值从0-255;Options 任务选项,如VX_UNBREAKABLE;stackSize 所分配的以字节为单位的堆栈大小;entryPt 开始执行的代码的地址;arg1…arg10 entryPt总共可以有10个参数;如果函数执行成功,则返回任务标识(id), 否则返回错误号。
3、产生死锁的原因(1) 竞争资源引起进程死锁2) 进程推进顺序不当引起死锁本实验中死锁产生的具体原因为:任务1锁住mutex1,并试图锁住mutex2;任务2锁住mutex2,并试图锁住mutex1, 造成死锁4、死锁的解决方法(1)避免一个任务同时锁住两个信号量2)semTake时不用WAIT_FOREVER,而是使用一个特定的超时参数3)顺序访问临界资源本实验中解决死锁的具体方法为:对资源进行顺序操作,任务1和任务2应该首先获取mutex1,然后再都获取信号量mutex2四、 程序设计1、变量共享资源定义为:resource;保护互斥信号量分别定义为:mutex1,mutex22、函数(1)初始化函数initResource()初始化函数用于创建保护共享资源的互斥信号量mutex1,mutex2;初始化共享资源resource2)资源使用函数useResource1()和useResource2()死锁产生:useResource1()中先锁住mutex1,再试图锁住mutex2;useResource2()中先锁住mutex2,再试图锁住mutex1代码如下所示void useResource1(){ semTake(mutex1, WAIT_FOREVER);taskDelay(1); semTake(mutex2, WAIT_FOREVER); semGive (mutex2); semGive (mutex1); resource++; }void useResource2(){ //死锁 semTake(mutex2, WAIT_FOREVER); semTake(mutex1, WAIT_FOREVER); semGive (mutex1); semGive (mutex2); resource++;}解决死锁:useResource1()函数主体不变,useResource2()的代码改为如下所示。
//解决死锁 semTake(mutex1, WAIT_FOREVER); semTake(mutex2, WAIT_FOREVER); semGive (mutex2); semGive (mutex1);(3)任务函数tLow()和tHigh()tLow()和tHigh()分别表示任务1和任务24)入口函数vxmain()vxmain()用于启动任务1和任务2五、 运行结果1、死锁情况下windview产生的图2、解决死锁情况下windview产生的图六、 总结通过本次实验,实现死锁以及解决死锁,本人了解了VxWorks进程间的通信机制,死锁产生原因以及解决死锁的方法,熟悉了对VxWorks互斥信号量的操作以及windview的使用七、 附录deadlock.cpp#include "vxWorks.h"#include "semLib.h"#include "taskLib.h"#include "stdio.h"void tLow();void tHigh();int resource;SEM_ID mutex1;SEM_ID mutex2;int initResource(void){ /*保护共享资源的互斥信号量创建*/ mutex1 = semMCreate (SEM_Q_PRIORITY|SEM_INVERSION_SAFE); mutex2 = semMCreate (SEM_Q_PRIORITY|SEM_INVERSION_SAFE); if ((NULL == mutex1)||(NULL == mutex2)) return ERROR; resource = 0; /*共享资源初始化*/ return OK;}void useResource1(){ semTake(mutex1, WAIT_FOREVER); taskDelay(1); semTake(mutex2, WAIT_FOREVER); semGive (mutex2); semGive (mutex1); resource++; }void useResource2(){//死锁 /* semTake(mutex2, WAIT_FOREVER); semTake(mutex1, WAIT_FOREVER); semGive (mutex2); semGive (mutex1);*///解决死锁 semTake(mutex1, WAIT_FOREVER); semTake(mutex2, WAIT_FOREVER); semGive (mutex2); semGive (mutex1); resource++;}/*-------------------------------------------------the 2 tasks-------------------------------------------------*/void tLow(){ useResource1();}void tHigh(){ useResource2();}void vxmain(){ int tLowId, tHighId; if (initResource()==ERROR) exit(0); tLowId=taskSpawn("tLow",81,0,1000,(FUNCPTR)tLow, 0,0,0,0,0,0,0,0,0,0); taskDelay(1); tHighId= taskSpawn("tHigh",80,0,1000,(FUNCPTR)tHigh, 0,0,0,0,0,0,0,0,0,0);}。





