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 1c2f0f63c8268c637854edd9403a295629fecf2b..8e323259f9279ea3a882c9ea0f2e9d52d4a5fbae 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,9 +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_sem_t dynamic_sem = RT_NULL; @@ -218,17 +220,23 @@ static void rt_thread1_entry(void *parameter) { static rt_uint8_t count = 0; - while(1) + while (1) { - if(count <= 100) + if (count <= 100) { count++; } else + { + rt_kprintf("thread1 exiting...\n"); + sem_flag = 1; + rt_sem_release(dynamic_sem); + count = 0; return; + } /* count 每计数 10 次,就释放一次信号量 */ - if(0 == (count % 10)) + if (0 == (count % 10)) { rt_kprintf("t1 release a dynamic semaphore.\n"); rt_sem_release(dynamic_sem); @@ -243,20 +251,22 @@ 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 (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 { number++; - rt_kprintf("t2 take a dynamic semaphore. number = %d\n" ,number); + rt_kprintf("t2 take a dynamic semaphore. number = %d\n", number); } } } @@ -291,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; @@ -305,30 +315,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 >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... + +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... ``` 如上面运行结果:线程 1 在 count 计数为 10 的倍数时(count 计数为 100 之后线程退出),发送一个信号量,线程 2 在接收信号量后,对 number 进行加 1 操作。 @@ -391,6 +428,7 @@ void producer_thread_entry(void *parameter) } rt_kprintf("the producer exit!\n"); + cnt = 0; } /* 消费者线程入口 */ @@ -422,6 +460,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 +520,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 +530,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 @@ -740,27 +807,44 @@ 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_uint8_t number1, number2 = 0; +/* 线程退出标志 */ +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 获取到互斥量后,先后对 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_flag) + { + number1 = 0; + number2 = 0; + + /* 重置退出标志 */ + thread_exit_flag = RT_FALSE; + break; /* 退出线程 */ + } + + /* 获取互斥量并进行操作 */ + if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) + { + number1++; + number2++; + rt_kprintf("thread1 mutex protect, number1 = number2 is %d\n", number1); + rt_mutex_release(dynamic_mutex); + rt_thread_mdelay(10); + } + } } ALIGN(RT_ALIGN_SIZE) @@ -768,26 +852,37 @@ 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) + { + thread_exit_flag = RT_TRUE; + + /* 删除互斥量 */ + rt_mutex_delete(dynamic_mutex); + dynamic_mutex = RT_NULL; + + break; /* 退出线程 */ + } + } + } } /* 互斥量示例的初始化 */ @@ -816,8 +911,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 +924,110 @@ 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 值保持一致。