|
|
@@ -0,0 +1,203 @@
|
|
|
+# 互斥量的使用 #
|
|
|
+
|
|
|
+## 介绍 ##
|
|
|
+
|
|
|
+这个例程展示了如何在RT-Thread里使用互斥量。
|
|
|
+
|
|
|
+## 程序清单 ##
|
|
|
+
|
|
|
+```{.c}
|
|
|
+/*
|
|
|
+ * 程序清单:互斥锁例程
|
|
|
+ *
|
|
|
+ * 互斥锁是一种保护共享资源的方法。当一个线程拥有互斥锁的时候,另一个线程若是等待锁,
|
|
|
+ * 则其就会被挂起,从而保证只有一个线程会操作共享数据。
|
|
|
+ *
|
|
|
+ */
|
|
|
+#include <rtthread.h>
|
|
|
+
|
|
|
+/* 互斥量控制块 */
|
|
|
+static struct rt_mutex static_mutex;
|
|
|
+/* 指向互斥量的指针 */
|
|
|
+static rt_mutex_t dynamic_mutex = RT_NULL;
|
|
|
+
|
|
|
+ALIGN(RT_ALIGN_SIZE)
|
|
|
+static char thread1_stack[1024];
|
|
|
+static struct rt_thread thread1;
|
|
|
+static void rt_thread_entry1(void *parameter)
|
|
|
+{
|
|
|
+ rt_err_t result;
|
|
|
+ rt_tick_t tick;
|
|
|
+
|
|
|
+ /* 1. staic mutex demo */
|
|
|
+
|
|
|
+ /* 试图持有互斥量,最大等待10个OS Tick后返回 */
|
|
|
+ rt_kprintf("thread1 try to get static mutex, wait 10 ticks.\n");
|
|
|
+
|
|
|
+ /* 获得当前的OS Tick */
|
|
|
+ tick = rt_tick_get();
|
|
|
+ result = rt_mutex_take(&static_mutex, 10);
|
|
|
+
|
|
|
+ if (result == -RT_ETIMEOUT)
|
|
|
+ {
|
|
|
+ /* 超时后判断是否刚好是10个OS Tick */
|
|
|
+ if (rt_tick_get() - tick != 10)
|
|
|
+ {
|
|
|
+ rt_mutex_detach(&static_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ rt_kprintf("thread1 take static mutex timeout\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* 线程2持有互斥量,且在相当长的时间后才会释放互斥量,
|
|
|
+ * 因此10个tick后线程1不可能获得 */
|
|
|
+ rt_kprintf("thread1 take a static mutex, failed.\n");
|
|
|
+ rt_mutex_detach(&static_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 永久等待方式持有互斥量 */
|
|
|
+ rt_kprintf("thread1 try to get static mutex, wait forever.\n");
|
|
|
+ result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
|
|
|
+ if (result != RT_EOK)
|
|
|
+ {
|
|
|
+ /* 不成功则测试失败 */
|
|
|
+ rt_kprintf("thread1 take a static mutex, failed.\n");
|
|
|
+ rt_mutex_detach(&static_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_kprintf("thread1 take a staic mutex, done.\n");
|
|
|
+
|
|
|
+ /* 脱离互斥量对象 */
|
|
|
+ rt_mutex_detach(&static_mutex);
|
|
|
+
|
|
|
+ /* 2. dynamic mutex test */
|
|
|
+
|
|
|
+ /* 试图持有互斥量,最大等待10个OS Tick后返回 */
|
|
|
+ rt_kprintf("thread1 try to get dynamic mutex, wait 10 ticks.\n");
|
|
|
+
|
|
|
+ tick = rt_tick_get();
|
|
|
+ result = rt_mutex_take(dynamic_mutex, 10);
|
|
|
+ if (result == -RT_ETIMEOUT)
|
|
|
+ {
|
|
|
+ /* 超时后判断是否刚好是10个OS Tick */
|
|
|
+ if (rt_tick_get() - tick != 10)
|
|
|
+ {
|
|
|
+ rt_mutex_delete(dynamic_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ rt_kprintf("thread1 take dynamic mutex timeout\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* 线程2持有互斥量,且在相当长的时间后才会释放互斥量,
|
|
|
+ * 因此10个tick后线程1不可能获得 */
|
|
|
+ rt_kprintf("thread1 take a dynamic mutex, failed.\n");
|
|
|
+ rt_mutex_delete(dynamic_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 永久等待方式持有互斥量 */
|
|
|
+ rt_kprintf("thread1 try to get dynamic mutex, wait forever.\n");
|
|
|
+ result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
|
|
|
+ if (result != RT_EOK)
|
|
|
+ {
|
|
|
+ /* 不成功则测试失败 */
|
|
|
+ rt_kprintf("thread1 take a dynamic mutex, failed.\n");
|
|
|
+ rt_mutex_delete(dynamic_mutex);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_kprintf("thread1 take a dynamic mutex, done.\n");
|
|
|
+ /* 删除互斥量对象 */
|
|
|
+ rt_mutex_delete(dynamic_mutex);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ALIGN(RT_ALIGN_SIZE)
|
|
|
+static char thread2_stack[1024];
|
|
|
+static struct rt_thread thread2;
|
|
|
+static void rt_thread_entry2(void *parameter)
|
|
|
+{
|
|
|
+ /* 1. static mutex test */
|
|
|
+ rt_kprintf("thread2 try to get static mutex\n");
|
|
|
+ rt_mutex_take(&static_mutex, 10);
|
|
|
+ rt_kprintf("thread2 got static mutex\n");
|
|
|
+ rt_thread_delay(RT_TICK_PER_SECOND);
|
|
|
+ rt_kprintf("thread2 release static mutex\n");
|
|
|
+ rt_mutex_release(&static_mutex);
|
|
|
+
|
|
|
+ /* 2. dynamic mutex test */
|
|
|
+ rt_kprintf("thread2 try to get dynamic mutex\n");
|
|
|
+ rt_mutex_take(dynamic_mutex, 10);
|
|
|
+ rt_kprintf("thread2 got dynamic mutex\n");
|
|
|
+ rt_thread_delay(RT_TICK_PER_SECOND);
|
|
|
+ rt_kprintf("thread2 release dynamic mutex\n");
|
|
|
+ rt_mutex_release(dynamic_mutex);
|
|
|
+}
|
|
|
+
|
|
|
+/* 互斥量示例的初始化 */
|
|
|
+int mutex_sample()
|
|
|
+{
|
|
|
+ rt_err_t result;
|
|
|
+
|
|
|
+ /* 初始化静态互斥量 */
|
|
|
+ result = rt_mutex(&static_mutex, "smutex", RT_IPC_FLAG_FIFO);
|
|
|
+ if (result != RT_EOK)
|
|
|
+ {
|
|
|
+ rt_kprintf("init static mutex failed.\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 创建一个动态互斥量 */
|
|
|
+ dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
|
|
|
+ if (dynamic_mutex == RT_NULL)
|
|
|
+ {
|
|
|
+ rt_kprintf("create dynamic mutex failed.\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_thread(&thread1,
|
|
|
+ "thread1",
|
|
|
+ rt_thread_entry1,
|
|
|
+ RT_NULL,
|
|
|
+ &thread1_stack[0],
|
|
|
+ sizeof(thread1_stack), 11, 5);
|
|
|
+ rt_thread_startup(&thread1);
|
|
|
+
|
|
|
+
|
|
|
+ rt_thread(&thread2,
|
|
|
+ "thread2",
|
|
|
+ rt_thread_entry2,
|
|
|
+ RT_NULL,
|
|
|
+ &thread2_stack[0],
|
|
|
+ sizeof(thread2_stack), 10, 5);
|
|
|
+ rt_thread_startup(&thread2);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 导出到 msh 命令列表中 */
|
|
|
+MSH_CMD_EXPORT(mutex_sample, mutex sample);
|
|
|
+```
|
|
|
+
|
|
|
+## 运行结果 ##
|
|
|
+
|
|
|
+```
|
|
|
+ \ | /
|
|
|
+- RT - Thread Operating System
|
|
|
+ / | \ 3.0.4 build Jul 17 2018
|
|
|
+ 2006 - 2018 Copyright by rt-thread team
|
|
|
+msh >mu
|
|
|
+mutex_sample
|
|
|
+msh >mutex_sample
|
|
|
+thread1 try to get static mutex, wait 10 ticks.
|
|
|
+thread1 take a static mutex, failed.
|
|
|
+thread2 try to get static mutex
|
|
|
+msh >thread2 got static mutex
|
|
|
+thread2 release static mutex
|
|
|
+thread2 try to get dynamic mutex
|
|
|
+thread2 got dynamic mutex
|
|
|
+thread2 release dynamic mutex
|
|
|
+```
|