本文共 3410 字,大约阅读时间需要 11 分钟。
生产者消费者问题:线程同步问题
生产者--->产品(带缓冲区)--->消费者
生产者生产产品放到缓冲区,消费者从缓冲区拿产品消费,当缓冲区中产品满了之后,生产者会挂起,只有当消费者消费了一个产品之后,缓冲区产生一个空位,生产者才会继续生产。
对于缓冲区的访问是互斥的,缓冲区满了生产者要挂起,缓冲区空了消费者要挂起。
使用RT-Thread任务同步的相关机制给出一个生产者-消费者模型
/* * 程序清单:信号量例程 * * 该例程创建了一个动态信号量和静态信号量,分别展示了获取信号量超时和获取成功的情况 * */#include/* 信号量控制块 */static struct rt_semaphore static_sem;/* 指向信号量的指针 */static rt_sem_t dynamic_sem = 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 semaphore demo */ /* 获得当前的OS Tick */ tick = rt_tick_get(); /* 试图持有信号量,最大等待10个OS Tick后返回 */ result = rt_sem_take(&static_sem, 10); if (result == -RT_ETIMEOUT) { /* 超时后判断是否刚好是10个OS Tick */ if (rt_tick_get() - tick != 10) { rt_sem_detach(&static_sem); return; } rt_kprintf("take semaphore timeout\n"); } else { /* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */ rt_kprintf("take a static semaphore, failed.\n"); rt_sem_detach(&static_sem); return; } /* 释放一次信号量 */ rt_sem_release(&static_sem); /* 永久等待方式持有信号量 */ result = rt_sem_take(&static_sem, RT_WAITING_FOREVER); if (result != RT_EOK) { /* 不成功则测试失败 */ rt_kprintf("take a static semaphore, failed.\n"); rt_sem_detach(&static_sem); return; } rt_kprintf("take a staic semaphore, done.\n"); /* 脱离信号量对象 */ rt_sem_detach(&static_sem); /* 2. dynamic semaphore test */ tick = rt_tick_get(); /* 试图持有信号量,最大等待10个OS Tick后返回 */ result = rt_sem_take(dynamic_sem, 10); if (result == -RT_ETIMEOUT) { /* 超时后判断是否刚好是10个OS Tick */ if (rt_tick_get() - tick != 10) { rt_sem_delete(dynamic_sem); return; } rt_kprintf("take semaphore timeout\n"); } else { /* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */ rt_kprintf("take a dynamic semaphore, failed.\n"); rt_sem_delete(dynamic_sem); return; } /* 释放一次信号量 */ rt_sem_release(dynamic_sem); /* 永久等待方式持有信号量 */ result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); if (result != RT_EOK) { /* 不成功则测试失败 */ rt_kprintf("take a dynamic semaphore, failed.\n"); rt_sem_delete(dynamic_sem); return; } rt_kprintf("take a dynamic semaphore, done.\n"); /* 删除信号量对象 */ rt_sem_delete(dynamic_sem);}/* 信号量示例的初始化 */int semaphore_sample_init(){ rt_err_t result; /* 初始化静态信号量,初始值是0 */ result = rt_sem_init(&static_sem, "ssem", 0, RT_IPC_FLAG_FIFO); if (result != RT_EOK) { rt_kprintf("init dynamic semaphore failed.\n"); return -1; } /* 创建一个动态信号量,初始值是0 */ dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO); if (dynamic_sem == RT_NULL) { rt_kprintf("create dynamic semaphore failed.\n"); return -1; } rt_thread_init(&thread1, "thread1", rt_thread_entry1, RT_NULL, &thread1_stack[0], sizeof(thread1_stack), 11, 5); rt_thread_startup(&thread1); return 0;}/* 如果设置了RT_SAMPLES_AUTORUN,则加入到初始化线程中自动运行 */#if defined (RT_SAMPLES_AUTORUN) && defined(RT_USING_COMPONENTS_INIT) INIT_APP_EXPORT(semaphore_sample_init);#endif/* 导出到 msh 命令列表中 */MSH_CMD_EXPORT(semaphore_sample_init, semaphore sample);
思考:互斥量如何实现?
转载地址:http://bswsi.baihongyu.com/