From 5c5963f02f0e0d1a10f09d7abbd2c333eaebac08 Mon Sep 17 00:00:00 2001 From: 286643536 <286643536@qq.com> Date: Mon, 2 Sep 2024 20:26:41 +0800 Subject: [PATCH 1/3] [alter]semaphore and mutex --- .../programming-manual/ipc1/ipc1.md | 331 ++++++++++++++---- 1 file changed, 263 insertions(+), 68 deletions(-) diff --git a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md index 1c2f0f6..84a5caf 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md @@ -207,7 +207,7 @@ rt_err_t rt_sem_release(rt_sem_t sem); #define THREAD_PRIORITY 25 #define THREAD_TIMESLICE 5 - +int sem_Flag = 0; //信号量退出标志,用于标志信号量退出 /* 指向信号量的指针 */ static rt_sem_t dynamic_sem = RT_NULL; @@ -225,7 +225,14 @@ static void rt_thread1_entry(void *parameter) count++; } else + { + rt_kprintf("thread1 exiting...\n"); + sem_Flag = 1; + rt_sem_release(dynamic_sem); + sem_Flag = 0; + count = 0; return; + } /* count 每计数 10 次,就释放一次信号量 */ if(0 == (count % 10)) @@ -247,10 +254,12 @@ static void rt_thread2_entry(void *parameter) { /* 永久方式等待信号量,获取到信号量,则执行 number 自加的操作 */ result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); - if (result != RT_EOK) + if (sem_Flag && result == RT_EOK) { - rt_kprintf("t2 take a dynamic semaphore, failed.\n"); + rt_kprintf("thread2 exiting...\n"); rt_sem_delete(dynamic_sem); + sem_Flag = 0; + number = 0; return; } else @@ -305,30 +314,57 @@ MSH_CMD_EXPORT(semaphore_sample, semaphore sample); ```c \ | / - RT - Thread Operating System - / | \ 3.1.0 build Aug 27 2018 - 2006 - 2018 Copyright by rt-thread team + / | \ 4.1.1 build Sep 2 2024 14:52:06 + 2006 - 2022 Copyright by RT-Thread team +msh >semaphore_sample +create done. dynamic semaphore value = 0. +msh >thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 1 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 2 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 3 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 4 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 5 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 6 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 7 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 8 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 9 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 10 +thread1 exiting... +thread2 exiting... + msh >semaphore_sample create done. dynamic semaphore value = 0. -msh >t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 1 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 2 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 3 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 4 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 5 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 6 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 7 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 8 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 9 -t1 release a dynamic semaphore. -t2 take a dynamic semaphore. number = 10 +msh >thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 1 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 2 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 3 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 4 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 5 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 6 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 7 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 8 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 9 +thread1 release a dynamic semaphore. +thread2 take a dynamic semaphore. number = 10 +thread1 exiting... +thread2 exiting... ``` 如上面运行结果:线程 1 在 count 计数为 10 的倍数时(count 计数为 100 之后线程退出),发送一个信号量,线程 2 在接收信号量后,对 number 进行加 1 操作。 @@ -391,6 +427,7 @@ void producer_thread_entry(void *parameter) } rt_kprintf("the producer exit!\n"); + cnt = 0; } /* 消费者线程入口 */ @@ -422,6 +459,10 @@ void consumer_thread_entry(void *parameter) rt_kprintf("the consumer sum is: %d\n", sum); rt_kprintf("the consumer exit!\n"); + rt_sem_detach(&sem_lock); + rt_sem_detach(&sem_empty); + rt_sem_detach(&sem_full); + sum = 0; } int producer_consumer(void) @@ -478,8 +519,8 @@ MSH_CMD_EXPORT(producer_consumer, producer_consumer sample); ```shell \ | / - RT - Thread Operating System - / | \ 3.1.0 build Aug 27 2018 - 2006 - 2018 Copyright by rt-thread team + / | \ 4.1.1 build Sep 2 2024 18:24:30 + 2006 - 2022 Copyright by RT-Thread team msh >producer_consumer the producer generates a number: 1 the consumer[0] get a number: 1 @@ -488,8 +529,33 @@ the producer generates a number: 3 the consumer[1] get a number: 2 the producer generates a number: 4 the producer generates a number: 5 +the consumer[2] get a number: 3 the producer generates a number: 6 +the producer generates a number: 7 +the producer generates a number: 8 +the consumer[3] get a number: 4 +the producer generates a number: 9 +the consumer[4] get a number: 5 +the producer generates a number: 10 +the producer exit! +the consumer[0] get a number: 6 +the consumer[1] get a number: 7 +the consumer[2] get a number: 8 +the consumer[3] get a number: 9 +the consumer[4] get a number: 10 +the consumer sum is: 55 +the consumer exit! + +msh >producer_consumer +the producer generates a number: 1 +the consumer[0] get a number: 1 +msh >the producer generates a number: 2 +the producer generates a number: 3 +the consumer[1] get a number: 2 +the producer generates a number: 4 +the producer generates a number: 5 the consumer[2] get a number: 3 +the producer generates a number: 6 the producer generates a number: 7 the producer generates a number: 8 the consumer[3] get a number: 4 @@ -745,22 +811,35 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex); /* 指向互斥量的指针 */ static rt_mutex_t dynamic_mutex = RT_NULL; -static rt_uint8_t number1,number2 = 0; +static rt_uint8_t number1, number2 = 0; +/* 线程退出标志 */ +static rt_bool_t thread_exit = RT_FALSE; ALIGN(RT_ALIGN_SIZE) static char thread1_stack[1024]; static struct rt_thread thread1; static void rt_thread_entry1(void *parameter) { - while(1) - { - /* 线程 1 获取到互斥量后,先后对 number1、number2 进行加 1 操作,然后释放互斥量 */ - rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); - number1++; - rt_thread_mdelay(10); - number2++; - rt_mutex_release(dynamic_mutex); - } + while (1) + { + /* 线程 1 在获取互斥量前检查它是否存在 */ + if (dynamic_mutex == RT_NULL || thread_exit) + { + number1 = 0; + number2 = 0; + + return; // 退出线程 + } + + /* 获取互斥量并进行操作 */ + if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) + { + number1++; + rt_thread_mdelay(10); + number2++; + rt_mutex_release(dynamic_mutex); + } + } } ALIGN(RT_ALIGN_SIZE) @@ -768,31 +847,53 @@ static char thread2_stack[1024]; static struct rt_thread thread2; static void rt_thread_entry2(void *parameter) { - while(1) - { - /* 线程 2 获取到互斥量后,检查 number1、number2 的值是否相同,相同则表示 mutex 起到了锁的作用 */ - rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); - if(number1 != number2) - { - rt_kprintf("not protect.number1 = %d, mumber2 = %d \n",number1 ,number2); - } - else - { - rt_kprintf("mutex protect ,number1 = mumber2 is %d\n",number1); - } - - number1++; - number2++; - rt_mutex_release(dynamic_mutex); - - if(number1>=50) - return; - } + while (1) + { + /* 获取互斥量 */ + if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) + { + if (number1 != number2) + { + rt_kprintf("not protect. number1 = %d, number2 = %d\n", number1, number2); + } + else + { + rt_kprintf("mutex protect, number1 = number2 is %d\n", number1); + } + + number1++; + number2++; + rt_mutex_release(dynamic_mutex); + + /* 判断是否达到退出条件 */ + if (number1 >= 50) + { + /* 删除互斥量,设置退出标志 */ + number1 = 0; + number2 = 0; + rt_mutex_delete(dynamic_mutex); + dynamic_mutex = RT_NULL; + thread_exit = RT_TRUE; + + return; + } + } + } } /* 互斥量示例的初始化 */ int mutex_sample(void) { + /* 检查并删除旧的互斥量 */ + if (dynamic_mutex != RT_NULL) + { + rt_mutex_delete(dynamic_mutex); + dynamic_mutex = RT_NULL; + } + + /* 重置退出标志 */ + thread_exit = RT_FALSE; + /* 创建一个动态互斥量 */ dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_PRIO); if (dynamic_mutex == RT_NULL) @@ -816,8 +917,9 @@ int mutex_sample(void) RT_NULL, &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY-1, THREAD_TIMESLICE); + THREAD_PRIORITY - 1, THREAD_TIMESLICE); rt_thread_startup(&thread2); + return 0; } @@ -828,18 +930,111 @@ MSH_CMD_EXPORT(mutex_sample, mutex sample); 线程 1 与线程 2 中均使用互斥量保护对 2 个 number 的操作(倘若将线程 1 中的获取、释放互斥量语句注释掉,线程 1 将对 number 不再做保护),仿真运行结果如下: ```shell - \ | / +\ | / - RT - Thread Operating System - / | \ 3.1.0 build Aug 24 2018 - 2006 - 2018 Copyright by rt-thread team + / | \ 4.1.1 build Sep 2 2024 19:21:00 + 2006 - 2022 Copyright by RT-Thread team +msh >mutex_sample +msh >mutex protect, number1 = number2 is 1 +mutex protect, number1 = number2 is 2 +mutex protect, number1 = number2 is 3 +mutex protect, number1 = number2 is 4 +mutex protect, number1 = number2 is 5 +mutex protect, number1 = number2 is 6 +mutex protect, number1 = number2 is 7 +mutex protect, number1 = number2 is 8 +mutex protect, number1 = number2 is 9 +mutex protect, number1 = number2 is 10 +mutex protect, number1 = number2 is 11 +mutex protect, number1 = number2 is 12 +mutex protect, number1 = number2 is 13 +mutex protect, number1 = number2 is 14 +mutex protect, number1 = number2 is 15 +mutex protect, number1 = number2 is 16 +mutex protect, number1 = number2 is 17 +mutex protect, number1 = number2 is 18 +mutex protect, number1 = number2 is 19 +mutex protect, number1 = number2 is 20 +mutex protect, number1 = number2 is 21 +mutex protect, number1 = number2 is 22 +mutex protect, number1 = number2 is 23 +mutex protect, number1 = number2 is 24 +mutex protect, number1 = number2 is 25 +mutex protect, number1 = number2 is 26 +mutex protect, number1 = number2 is 27 +mutex protect, number1 = number2 is 28 +mutex protect, number1 = number2 is 29 +mutex protect, number1 = number2 is 30 +mutex protect, number1 = number2 is 31 +mutex protect, number1 = number2 is 32 +mutex protect, number1 = number2 is 33 +mutex protect, number1 = number2 is 34 +mutex protect, number1 = number2 is 35 +mutex protect, number1 = number2 is 36 +mutex protect, number1 = number2 is 37 +mutex protect, number1 = number2 is 38 +mutex protect, number1 = number2 is 39 +mutex protect, number1 = number2 is 40 +mutex protect, number1 = number2 is 41 +mutex protect, number1 = number2 is 42 +mutex protect, number1 = number2 is 43 +mutex protect, number1 = number2 is 44 +mutex protect, number1 = number2 is 45 +mutex protect, number1 = number2 is 46 +mutex protect, number1 = number2 is 47 +mutex protect, number1 = number2 is 48 +mutex protect, number1 = number2 is 49 + msh >mutex_sample -msh >mutex protect ,number1 = mumber2 is 1 -mutex protect ,number1 = mumber2 is 2 -mutex protect ,number1 = mumber2 is 3 -mutex protect ,number1 = mumber2 is 4 -… -mutex protect ,number1 = mumber2 is 48 -mutex protect ,number1 = mumber2 is 49 +msh >mutex protect, number1 = number2 is 1 +mutex protect, number1 = number2 is 2 +mutex protect, number1 = number2 is 3 +mutex protect, number1 = number2 is 4 +mutex protect, number1 = number2 is 5 +mutex protect, number1 = number2 is 6 +mutex protect, number1 = number2 is 7 +mutex protect, number1 = number2 is 8 +mutex protect, number1 = number2 is 9 +mutex protect, number1 = number2 is 10 +mutex protect, number1 = number2 is 11 +mutex protect, number1 = number2 is 12 +mutex protect, number1 = number2 is 13 +mutex protect, number1 = number2 is 14 +mutex protect, number1 = number2 is 15 +mutex protect, number1 = number2 is 16 +mutex protect, number1 = number2 is 17 +mutex protect, number1 = number2 is 18 +mutex protect, number1 = number2 is 19 +mutex protect, number1 = number2 is 20 +mutex protect, number1 = number2 is 21 +mutex protect, number1 = number2 is 22 +mutex protect, number1 = number2 is 23 +mutex protect, number1 = number2 is 24 +mutex protect, number1 = number2 is 25 +mutex protect, number1 = number2 is 26 +mutex protect, number1 = number2 is 27 +mutex protect, number1 = number2 is 28 +mutex protect, number1 = number2 is 29 +mutex protect, number1 = number2 is 30 +mutex protect, number1 = number2 is 31 +mutex protect, number1 = number2 is 32 +mutex protect, number1 = number2 is 33 +mutex protect, number1 = number2 is 34 +mutex protect, number1 = number2 is 35 +mutex protect, number1 = number2 is 36 +mutex protect, number1 = number2 is 37 +mutex protect, number1 = number2 is 38 +mutex protect, number1 = number2 is 39 +mutex protect, number1 = number2 is 40 +mutex protect, number1 = number2 is 41 +mutex protect, number1 = number2 is 42 +mutex protect, number1 = number2 is 43 +mutex protect, number1 = number2 is 44 +mutex protect, number1 = number2 is 45 +mutex protect, number1 = number2 is 46 +mutex protect, number1 = number2 is 47 +mutex protect, number1 = number2 is 48 +mutex protect, number1 = number2 is 49 ``` 线程使用互斥量保护对两个 number 的操作,使 number 值保持一致。 -- Gitee From 6b6e8a93c37fccd69f1edc692bd4b8b8833c1323 Mon Sep 17 00:00:00 2001 From: 286643536 <286643536@qq.com> Date: Wed, 4 Sep 2024 21:09:07 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[alter]=E4=BF=AE=E6=94=B9semaphore=5Fsample?= =?UTF-8?q?=20=E4=B8=ADsem=5Fflag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rt-thread-standard/programming-manual/ipc1/ipc1.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md index 84a5caf..7c2fdac 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md @@ -207,7 +207,8 @@ rt_err_t rt_sem_release(rt_sem_t sem); #define THREAD_PRIORITY 25 #define THREAD_TIMESLICE 5 -int sem_Flag = 0; //信号量退出标志,用于标志信号量退出 + +static rt_bool_t sem_flag = 0; //信号量退出标志,用于标志信号量退出 /* 指向信号量的指针 */ static rt_sem_t dynamic_sem = RT_NULL; @@ -227,9 +228,8 @@ static void rt_thread1_entry(void *parameter) else { rt_kprintf("thread1 exiting...\n"); - sem_Flag = 1; + sem_flag = 1; rt_sem_release(dynamic_sem); - sem_Flag = 0; count = 0; return; } @@ -254,11 +254,11 @@ static void rt_thread2_entry(void *parameter) { /* 永久方式等待信号量,获取到信号量,则执行 number 自加的操作 */ result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); - if (sem_Flag && result == RT_EOK) + if (sem_flag && result == RT_EOK) { rt_kprintf("thread2 exiting...\n"); rt_sem_delete(dynamic_sem); - sem_Flag = 0; + sem_flag = 0; number = 0; return; } -- Gitee From 49daa17a19d1822f16a01443aa8080947c3445dd Mon Sep 17 00:00:00 2001 From: 286643536 <286643536@qq.com> Date: Thu, 5 Sep 2024 20:25:04 +0800 Subject: [PATCH 3/3] =?UTF-8?q?[alter]mutex=5Fsample=20and=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../programming-manual/ipc1/ipc1.md | 57 ++++++++----------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md index 7c2fdac..8e32325 100644 --- a/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md +++ b/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1.md @@ -205,10 +205,11 @@ rt_err_t rt_sem_release(rt_sem_t sem); ```c #include -#define THREAD_PRIORITY 25 -#define THREAD_TIMESLICE 5 +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 5 -static rt_bool_t sem_flag = 0; //信号量退出标志,用于标志信号量退出 +/* 信号量退出标志 */ +static rt_bool_t sem_flag = 0; /* 指向信号量的指针 */ static rt_sem_t dynamic_sem = RT_NULL; @@ -219,9 +220,9 @@ static void rt_thread1_entry(void *parameter) { static rt_uint8_t count = 0; - while(1) + while (1) { - if(count <= 100) + if (count <= 100) { count++; } @@ -235,7 +236,7 @@ static void rt_thread1_entry(void *parameter) } /* count 每计数 10 次,就释放一次信号量 */ - if(0 == (count % 10)) + if (0 == (count % 10)) { rt_kprintf("t1 release a dynamic semaphore.\n"); rt_sem_release(dynamic_sem); @@ -250,11 +251,11 @@ static void rt_thread2_entry(void *parameter) { static rt_err_t result; static rt_uint8_t number = 0; - while(1) + while (1) { /* 永久方式等待信号量,获取到信号量,则执行 number 自加的操作 */ result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); - if (sem_flag && result == RT_EOK) + if (sem_flag && result == RT_EOK) { rt_kprintf("thread2 exiting...\n"); rt_sem_delete(dynamic_sem); @@ -265,7 +266,7 @@ static void rt_thread2_entry(void *parameter) else { number++; - rt_kprintf("t2 take a dynamic semaphore. number = %d\n" ,number); + rt_kprintf("t2 take a dynamic semaphore. number = %d\n", number); } } } @@ -300,7 +301,7 @@ int semaphore_sample(void) RT_NULL, &thread2_stack[0], sizeof(thread2_stack), - THREAD_PRIORITY-1, THREAD_TIMESLICE); + THREAD_PRIORITY - 1, THREAD_TIMESLICE); rt_thread_startup(&thread2); return 0; @@ -806,38 +807,42 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex); ```c #include -#define THREAD_PRIORITY 8 -#define THREAD_TIMESLICE 5 +#define THREAD_PRIORITY 8 +#define THREAD_TIMESLICE 5 /* 指向互斥量的指针 */ static rt_mutex_t dynamic_mutex = RT_NULL; static rt_uint8_t number1, number2 = 0; /* 线程退出标志 */ -static rt_bool_t thread_exit = RT_FALSE; +static rt_bool_t thread_exit_flag = RT_FALSE; ALIGN(RT_ALIGN_SIZE) static char thread1_stack[1024]; static struct rt_thread thread1; + static void rt_thread_entry1(void *parameter) { while (1) { /* 线程 1 在获取互斥量前检查它是否存在 */ - if (dynamic_mutex == RT_NULL || thread_exit) + if (dynamic_mutex == RT_NULL || thread_exit_flag) { number1 = 0; number2 = 0; - return; // 退出线程 + /* 重置退出标志 */ + thread_exit_flag = RT_FALSE; + break; /* 退出线程 */ } /* 获取互斥量并进行操作 */ if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) { number1++; - rt_thread_mdelay(10); number2++; + rt_kprintf("thread1 mutex protect, number1 = number2 is %d\n", number1); rt_mutex_release(dynamic_mutex); + rt_thread_mdelay(10); } } } @@ -868,14 +873,13 @@ static void rt_thread_entry2(void *parameter) /* 判断是否达到退出条件 */ if (number1 >= 50) { - /* 删除互斥量,设置退出标志 */ - number1 = 0; - number2 = 0; + thread_exit_flag = RT_TRUE; + + /* 删除互斥量 */ rt_mutex_delete(dynamic_mutex); dynamic_mutex = RT_NULL; - thread_exit = RT_TRUE; - return; + break; /* 退出线程 */ } } } @@ -884,16 +888,6 @@ static void rt_thread_entry2(void *parameter) /* 互斥量示例的初始化 */ int mutex_sample(void) { - /* 检查并删除旧的互斥量 */ - if (dynamic_mutex != RT_NULL) - { - rt_mutex_delete(dynamic_mutex); - dynamic_mutex = RT_NULL; - } - - /* 重置退出标志 */ - thread_exit = RT_FALSE; - /* 创建一个动态互斥量 */ dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_PRIO); if (dynamic_mutex == RT_NULL) @@ -984,7 +978,6 @@ mutex protect, number1 = number2 is 46 mutex protect, number1 = number2 is 47 mutex protect, number1 = number2 is 48 mutex protect, number1 = number2 is 49 - msh >mutex_sample msh >mutex protect, number1 = number2 is 1 mutex protect, number1 = number2 is 2 -- Gitee