RT-Thread: Design pattern of the Producer-consumer model (Semaphore)
来源:互联网 发布:大连淘车网络和中软卓 编辑:程序博客网 时间:2024/05/16 04:22
Lower layer APIs concerning to RT-Thread can be found on
http://www.rt-thread.org/phpBB3/
1. General description:
RT-Thread is an open source real-time operating system for embedded devices from China, which has strong scalability: from a tiny kernel runnning on a tiny core, for example ARM Cortex-M, or Cortex-M3/4/7, to a rich feature system running on ARM Cortex-A8, ARM Cortex-A9 DualCore etc.
The producer/consumer design pattern is based on the master/Slave design pattern which used to decouple processes that produce data., and those that consume the data produced. Data queues are used to communicate data between loops in the Producer/Consumer design pattern. These queues offer the advantage of data buffering between producer and consumer loops.
The model is commonly used when acquiring multiple sets of data to be processed in order. Suppose you want to write an application that accepts data while processing them in the order they were received. Because queuing up this data is much faster than the actual processing, the Producer/Consumer design pattern is best suited for this application. We could conceivably put both the producer and consumer in the same loop for this application, but the processing queue will not be able to add any additional data until the first piece of data is done processing. The producer/consumer pattern approach to this application would be to queue the data in the producer loop, and have the actual processing done in the consumer loop. This in effect will allow the consumer loop to process the data at its own pace, while allowing the producer loop to queue additional data at the same time.
A semaphore is a lightweight kernel object that solves the problem of thread synchronization. Threads can acquire or release it to achieve the purpose of synchronization or mutual exclusion. The semaphore is like a key that locks a critical area and allows only a key thread to be accessed: the thread gets the key before it is allowed to enter the critical area; after leaving the key is passed to the queue wait for the thread, so that follow-up thread into the critical area in turn.
2. APIs description:
I'll provide some APIs concerning to semaphore here.
1) Create the semaphore, the kernel firstly creates a semaphore controlling module, then do the initialization work.
2) Delete the semaphore. Once delete it when a thread is waiting for it, the delete operation will awake the thread on the semaphore. And the return value to the thread is RT_ERROR.
3) Detach the semaphore, move away the object of the semaphore from the kernel.
4) Provide the thread to achieve semaphore resources. When the semaphore is over than zero, the thread
will achieve the semaphore.
5) Release the semaphore, when the thread has completely visited the resources, release the semaphore as soon as possible.
3. Test and Codes:
/* * File : application.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rt-thread.org/license/LICENSE * * Change Logs: * Date Author Notes * 2017-02-11 Kyrie the first version * 2014-02-15 Kyrie make code cleanup. */#include <board.h>#include <rtthread.h>#include <dfs_posix.h>//#include "tc_comm.h"//debugging interface#ifdef RT_USING_GDB#include <gdb_stub.h>#endif//#include <sha1.h>/*************zzh******************+*/#define MAXSEM 5#define THREAD_PRIORITY 25#define THREAD_STACK_SIZE 512#define THREAD_TIMESLICE 5rt_uint32_t array[MAXSEM];static rt_uint32_t set, get;static rt_thread_t producer_tid = RT_NULL;static rt_thread_t consumer_tid = RT_NULL;struct rt_semaphore sem_lock;struct rt_semaphore sem_empty, sem_full;/*************zzh******************-*/extern void rt_hw_led_set_on(rt_uint8_t led);extern void rt_hw_led_set_off(rt_uint8_t led);/*************zzh******************+*///static rt_thread_t tid = RT_NULL, tid2 = RT_NULL;static rt_sem_t sem = RT_NULL;//sem structstatic rt_thread_t tid = RT_NULL;/*************zzh******************-*/#define MASTER_KEY "electrical lift controller"/*************zzh******************+*//*static struct rt_thread thread1;ALIGN(4)static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];static struct rt_thread thread2;ALIGN(4)static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];*//*************zzh******************-*///static rt_thread_t tid = RT_NULL;//static rt_thread_t tid2 = RT_NULL;//static rt_uint32_t cnt;static rt_uint32_t test=0;void rt_init_thread_entry2(void* parameter){rt_uint32_t count = 0;rt_uint32_t no = (rt_uint32_t) parameter;while(1){rt_kprintf("thread%d count: %d\n", no, count ++);//rt_thread_delay(10);//rt_thread_yield();}}static void rt_init_thread_entry(void* parameter){//#ifdef RT_USING_COMPONENTS_INIT /* RT-Thread components initialization */// rt_components_init();//#endif//rt_kprintf("Hello RT-Thread !!!\n");/*************zzh******************+*///create a thread//rt_uint32_t count = 0;//rt_uint32_t no = (rt_uint32_t) parameter;//rt_uint32_t no;//no = (rt_uint32_t) parameter;rt_err_t result;rt_tick_t tick;tick = rt_tick_get();result = rt_sem_take(sem, 10);if (result == -RT_ETIMEOUT){if(rt_tick_get()-tick!=10){rt_sem_delete(sem);return;}rt_kprintf("take semaphore timeout\n");}else{rt_sem_delete(sem);return;}rt_sem_release(sem);result = rt_sem_take(sem, RT_WAITING_FOREVER);if (result != RT_EOK){rt_sem_delete(sem);return;}rt_sem_delete(sem);/*********zzh******************-*//* SHA-1 test *//*{ sha1_context ctx; rt_uint8_t output[20]; rt_uint8_t input[4] = {0x30,0x31,0x32,0x33}; rt_uint8_t usr_sn[16];*/ /* generate usr_key *//* sha1_hmac_reset(&ctx); sha1_hmac_starts(&ct x,MASTER_KEY,rt_strlen(MASTER_KEY)); sha1_hmac_update(&ctx,input,4); sha1_hmac_finish(&ctx,output); rt_memcpy(usr_sn,&output[4],16);*/ /* SEC0 KEYA */ /* sha1_hmac_reset(&ctx); sha1_hmac_starts(&ctx,usr_sn,16); sha1_hmac_update(&ctx,"SEC0KEYA",8); sha1_hmac_finish(&ctx,output); rt_kprintf("SHA1-HMAC SEC0 KEYA end...\n");*/ /* SEC0 KEYB */ /* sha1_hmac_reset(&ctx); sha1_hmac_starts(&ctx,usr_sn,16); sha1_hmac_update(&ctx,"SEC0KEYB",8); sha1_hmac_finish(&ctx,output); rt_kprintf("SHA1-HMAC SEC0 KEYA end...\n");}*/while(1){static rt_uint8_t tickCount = 0;rt_hw_led_set_on(tickCount);rt_hw_led_set_off(~tickCount);rt_thread_delay(RT_TICK_PER_SECOND);tickCount++;}}int semaphore_dynamic_init(){sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);if(sem== RT_NULL){//tc_stat(TC_STAT_END | TC_STAT_FAILED);return 0;}tid = rt_thread_create("thread", rt_init_thread_entry,(void*)0,THREAD_STACK_SIZE,THREAD_PRIORITY,THREAD_TIMESLICE);if(tid != RT_NULL)rt_thread_startup(tid);return 0;}void consumer_thread_entry(void* parameter){rt_uint32_t no;rt_uint32_t sum = 0;no = (rt_uint32_t)parameter;while(1){rt_sem_take(&sem_full, RT_WAITING_FOREVER);rt_sem_take(&sem_lock, RT_WAITING_FOREVER);sum += array[get%MAXSEM];rt_kprintf("the consumer[%d] get a number:%d\n",no, array[get%MAXSEM]);get++;rt_sem_release(&sem_lock);rt_sem_release(&sem_empty);if (get == 100) break;rt_thread_delay(10);}rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);rt_kprintf("the consumer[%d] exit!\n");}void producer_thread_entry(void* parameter){rt_int32_t cnt = 0;while(cnt <= 100){rt_sem_take(&sem_empty, RT_WAITING_FOREVER);rt_sem_take(&sem_lock, RT_WAITING_FOREVER);array[set%MAXSEM] = cnt + 1;rt_kprintf("the producer generates a number: %d\n",array[set%MAXSEM]);set++;rt_sem_release(&sem_lock);rt_sem_release(&sem_full);cnt++;rt_thread_delay(10);}rt_kprintf("the producer exit!\n");}int semaphore_producer_consumer_init(){rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO);rt_sem_init(&sem_empty,"empty", MAXSEM, RT_IPC_FLAG_FIFO);rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO);producer_tid = rt_thread_create("producer",producer_thread_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);if (producer_tid != RT_NULL)rt_thread_startup(producer_tid);consumer_tid = rt_thread_create("consumer",consumer_thread_entry,RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);if (consumer_tid != RT_NULL)rt_thread_startup(consumer_tid);return 0;}int rt_application_init(){ //semaphore_dynamic_init();semaphore_producer_consumer_init(); /* rt_thread_t tid; tid = rt_thread_create("t1", rt_init_thread_entry,(void*)10, 2048, 10, 5); if (tid != RT_NULL) rt_thread_startup(tid);*//*************zzh******************+*///rt_thread_t tid2;/*tid = rt_thread_create("t2", rt_init_thread_entry,(void*)20,2048,20,5);if (tid != RT_NULL) rt_thread_startup(tid);*//*************zzh******************-*//*************zzh******************+*//*rt_err_t result;result = rt_thread_init(&thread1, "t1", rt_init_thread_entry, (void*)1, &thread1_stack[0], sizeof(thread1_stack), THREAD_PRIORITY, 10);if (result == RT_EOK) rt_thread_startup(&thread1);elsereturn -1;result = rt_thread_init(&thread1, "t2", rt_init_thread_entry, (void*)2, &thread1_stack[0], sizeof(thread2_stack), THREAD_PRIORITY+1, 10);if (result == RT_EOK) rt_thread_startup(&thread2);elsereturn -1;*//*************zzh******************-*/ return 0;}/*@}*/
Author: Kyrie
- RT-Thread: Design pattern of the Producer-consumer model (Semaphore)
- Semaphore Consumer-Producer Code
- An Analysis of the Producer-Consumer Problem
- Producer/Consumer Model(pthread)
- Python producer & consumer model
- Producer consumer model
- Producer-Consumer Pattern
- Producer-Consumer Pattern
- Producer-Consumer Pattern
- Java Thread Producer/Consumer
- The Producer-Consumer Problem
- Producer Consumer problem - mutex and semaphore
- THE MODEL-VIEW-VIEWMODEL (MVVM) DESIGN PATTERN
- Java线程之Producer-Consumer Pattern
- Internet高级编程作业:Producer-consumer problem implemented by semaphore
- The Design of Model (part 1)
- The Design of Model (part 2)
- The basic principles of design pattern
- Android 7.0 Audio的Resample过程详解
- 查看mysql版本的四种方法
- Android样式的开发:shape篇
- 类模板成员函数
- Centos 配置eth0 提示Device does not seem to be present
- RT-Thread: Design pattern of the Producer-consumer model (Semaphore)
- redis特点及windows下安装使用
- 【JQuery】熟能生巧JQuery(一)——目录
- C#复习 2017-3-29
- 1009. 说反话 (20)-PAT乙级
- lintcode 173 链表插入排序
- ESB v6.6中新版本构件库XMLDatabaseUtil不支持中文
- 1005. Spell It Right (20)
- Android优化之插件开发(动态加载Apk)