📄 mutexsemdemo.c
字号:
/* mutexSemDemo.c - 使用互斥信号量保护共享资源的例子 */ #include "vxWorks.h" #include "semLib.h" #include "taskLib.h" #include "logLib.h" #include "sysLib.h" #include "stdio.h" #define CONSUMER_TASK_PRI 98 #define PRODUCER_TASK_PRI 99 #define TASK_STACK_SIZE 5000 #define PRODUCED 1 #define CONSUMED 0 #define NUM_ITEMS 3 /* 总共处理的次数 */ struct shMem /* 共享内存结构体 */ { int tid; /* 任务号*/ int count; /*处理的次数 */ int status; /* 状态 0 : consumed 1 : produced*/ }; LOCAL STATUS protectSharedResource (); LOCAL STATUS releaseProtectedSharedResource (); LOCAL STATUS producerTask (); LOCAL STATUS consumerTask (); LOCAL struct shMem shMemResource; /*共享内存*/ LOCAL SEM_ID mutexSemId; /* 互斥信号量的ID*/ LOCAL BOOL notFinished; /* 完成的标志 */ /***************************************************************************** * mutexSemDemo - 主函数 * * DESCRIPTION * 创建两个任务producerTask 和consumerTask,两个任务是通过共享内存的方式通信, * 都可能 读写全局变量shMemResource,为了防止两个任务同时访问shMemResource, * 使用互斥信号量进行保护. * * RETURNS: OK or ERROR * * EXAMPLE * * -> sp mutexSemDemo * */ STATUS mutexSemDemo() { notFinished = TRUE; /* 创建互斥信号量, 属性为优先级方式, 避免删除信号量占有任务,允许优先级继承*/ if ((mutexSemId = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)) == NULL) { perror ("Error in creating mutual exclusion semaphore"); return (ERROR); } /* 创建任务 consumerTask */ if (taskSpawn ("tConsumerTask", CONSUMER_TASK_PRI, 0, TASK_STACK_SIZE, (FUNCPTR) consumerTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) { perror ("consumerTask: Error in spawning demoTask"); return (ERROR); } /* 创建任务 producerTask */ if (taskSpawn ("tProducerTask", PRODUCER_TASK_PRI, 0, TASK_STACK_SIZE, (FUNCPTR) producerTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) { perror ("producerTask: Error in spawning demoTask"); return (ERROR); } /* 轮询结束标志 */ while (notFinished) taskDelay (sysClkRateGet ()); /* 删除信号量*/ if (semDelete (mutexSemId) == ERROR) { perror ("Error in deleting mutual exclusion semaphore"); return (ERROR); } return (OK); } /***************************************************************************** * producerTask - 产生信息的任务,向共享内存shMemResource 赋值 * * RETURNS: OK or ERROR * */ LOCAL STATUS producerTask () { int count = 0; int notDone = TRUE; while (notDone) { /* 循环NUM_ITEMS 次 */ if (count < NUM_ITEMS) { /* 等待共享资源变为可用 */ if (protectSharedResource() == ERROR) return (ERROR); /* 赋值 */ if (shMemResource.status == CONSUMED) { count++; shMemResource.tid = taskIdSelf (); shMemResource.count = count; shMemResource.status = PRODUCED; } /* 释放控制权 */ if (releaseProtectedSharedResource () == ERROR) return (ERROR); logMsg ("ProducerTask: tid = %#x, producing item = %d\n", taskIdSelf (), count,0,0,0,0); taskDelay (sysClkRateGet()/6); } else notDone = FALSE; } return (OK); } /***************************************************************************** * consumerTask - 通过共享内存shMemResource 取得信息,并将status变为CONSUMED * * RETURNS: OK or ERROR * */ LOCAL STATUS consumerTask () { int notDone = TRUE; while (notDone) { taskDelay (sysClkRateGet()/6); /* 等待共享资源变为可用 */ if (protectSharedResource() == ERROR) return (ERROR); /* 访问共享资源 */ if ((shMemResource.status == PRODUCED) && (shMemResource.count > 0)) { logMsg ("ConsumerTask: Consuming item = %d from tid = %#x\n\n", shMemResource.count, shMemResource.tid,0,0,0,0); shMemResource.status = CONSUMED; } if (shMemResource.count >= NUM_ITEMS) notDone = FALSE; /* 释放控制权 */ if (releaseProtectedSharedResource () == ERROR) return (ERROR); } notFinished = FALSE; return (OK); } /***************************************************************************** * protectSharedResource - semTake 得到共享资源的访问权 * * RETURNS: OK or ERROR * */ LOCAL STATUS protectSharedResource () { if (semTake (mutexSemId, WAIT_FOREVER) == ERROR) { perror ("protectSharedResource: Error in semTake"); return (ERROR); } else return (OK); } /***************************************************************************** * releaseProtectedSharedResource - semGive 释放共享资源的控制权 * * RETURNS: OK or ERROR * */ LOCAL STATUS releaseProtectedSharedResource () { if (semGive (mutexSemId) == ERROR) { perror ("protectSharedResource: Error in semTake"); return (ERROR); } else return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -