Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
关于线程的问题:注释掉第15条语句,由于线程2(20)比线程1(18)优先级低,那么线程2还能执行么?
发布于 2009-09-05 08:32:04 浏览:8186
订阅该版
1、void consumer_thread_entry(void *parameter) 2、{ 3、 rt_uint32_t no,sum; 4、 no=(rt_uint32_t)parameter; 5、 while(1) 6、 { 7、 rt_sem_take(&sem_full,RT_WAITING_FOREVER); 8、 rt_sem_take(&sem_lock,RT_WAITING_FOREVER); 9、 sum+=array[get%MAXSEM]; 10、 rt_kprintf("The consumer[%d} get anumber: %d
",no,array[get%MAXSEM]); 11、 get++; 12、 rt_sem_release(&sem_lock); 13、 rt_sem_release(&sem_empty); 14、 if(get==100) break; //注释掉下面的一句话,由于线程2比线程1优先级低,那么线程2还能执行么? 15、 // rt_thread_delay(10); 16、 } 17、 rt_kprintf("The consumer[%d] sum is %d
",no,sum); 18、 rt_kprintf("The consumer[%d] exit!
",no); 19、} 20、int application_tread_init(void) 21、{ 22、 rt_thread_t p,s; 23、 rt_sem_init(&sem_lock,"lock", 1,RT_IPC_FLAG_FIFO); 24、 rt_sem_init(&sem_empty,"empty",MAXSEM,RT_IPC_FLAG_FIFO); 25、 rt_sem_init(&sem_full,"full",0,RT_IPC_FLAG_FIFO); 26、 p=rt_thread_create("p",producer_thread_entry,RT_NULL,1024,18,10); 27、 rt_thread_startup(p); 28、 s=rt_thread_create("s1",consumer_thread_entry,(void*)1,1024,18,5); 29、 if(s!=RT_NULL) rt_thread_startup(s); 30、 s=rt_thread_create("s2",consumer_thread_entry,(void*)2,1024,20,5); 31、 if(s!=RT_NULL) rt_thread_startup(s); 32、 return 0; 33、}
查看更多
11
个回答
默认排序
按发布时间排序
xfocus
2009-09-05
这家伙很懒,什么也没写!
找到出处了 RT-Thread Programming Guide, Release 0.3.0 22 Chapter 3. 快速入门 3.6 生产者消费者问题 生产者消费者问题是操作系统中的一个经典问题,在嵌入式操作系统中也经常能够遇到, 例如串口中接收到数据,然后由一个任务统一的进行数据的处理:串口产生数据,任务作 为一个消费者消费数据。 在下面的例子中,将用RT-Thread的编程模式来实现一个生产者、消费者问题的解决代 码。 ``` #include
/* 定义最大5个元素能够被产生 */ #define MAXSEM 5 /* 用于放置生产的整数数组 */ rt_uint32_t array[MAXSEM]; struct rt_semaphore sem_lock; struct rt_semaphore sem_empty, sem_full; /* 指向生产者、消费者在array数组中的读写位置 */ static rt_uint32_t set, get; /* 生成者线程入口 */ void producer_thread_entry(void* parameter) { int cnt = 0; /* 运行100次 */ while( cnt < 100) { /* 获取一个空位 */ rt_sem_take(&sem_empty, RT_WAITING_FOREVER); /* 修改array内容,上锁 */ rt_sem_take(&sem_lock, RT_WAITING_FOREVER); array[set%MAXSEM] = cnt + 1; rt_kprintf("the producer generates a number: %d ", array[set%MAXSEM]); set++; rt_sem_release(&sem_lock); /* 发布一个满位 */ rt_sem_release(&sem_full); cnt++; /* 暂停一段时间 */ rt_thread_delay(50); } rt_kprintf("the producer exit! "); } /* 消费者线程入口 */ void consumer_thread_entry(void* parameter) { rt_uint32_t no; rt_uint32_t sum; /* 第n个线程,由入口参数传进来 */ 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 ", no, array[get%MAXSEM] ); get++; rt_sem_release(&sem_lock); /* 释放一个空位 */ rt_sem_release(&sem_empty); /* 生产者生产到100个数目,停止,消费者线程相应停止 */ if (get == 100) break; /* 暂停一小会时间 */ rt_thread_delay(10); } rt_kprintf("the consumer[%d] sum is %d ", no, sum); rt_kprintf("the consumer[%d] exit! "); } /** * This function will be invoked to initalize user application when system startup. */ int rt_application_init() { rt_thread_t p, s; /* 初始3个信号量 */ 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); /* 创建 生产者 线程 */ p = rt_thread_create("p", producer_thread_entry, RT_NULL, 1024, 18, 5); rt_thread_startup(p); /* 创建 消费者 线程,入口相同,入口参数不同,优先级相同 */ s = rt_thread_create("s1", consumer_thread_entry, (void *)1, 1024, 20, 5); if (s != RT_NULL) rt_thread_startup(s); s = rt_thread_create("s2", consumer_thread_entry, (void *)2, 1024, 20, 5); if (s != RT_NULL) rt_thread_startup(s); return 0; } ``` 在上面的例子中,系统启动了一个生产者线程p,用于向仓库(array数组)中产生一个整 数(1 到100);启动了两个消费者线程s1和s2,它们的入口函数是同一个,只是通过入口 参数分辨它们是第一个消费者线程还是第二个消费者线程。这两个消费者线程将同时从仓 库中获取生成的整数,然后把它打印出来。
xfocus
2009-09-05
这家伙很懒,什么也没写!
线程2应该是得不到执行了。生产者只要生产出产品都会被高优先级的线程1得到。
mgdsun2000
2009-09-05
这家伙很懒,什么也没写!
>线程2应该是得不到执行了。生产者只要生产出产品都会被高优先级的线程1得到。 --- 有没有不同的意见的
mgdsun2000
2009-09-07
这家伙很懒,什么也没写!
下面是我上面程序运行的结果 The producer generates a number: 1 The consumer[1} get anumber: 1 The producer generates a number: 2 The consumer[1} get anumber: 2 The producer generates a number: 3 The consumer[2} get anumber: 3 The producer generates a number: 4 The consumer[1} get anumber: 4 The producer generates a number: 5 The consumer[2} get anumber: 5
bernard
2009-09-07
这家伙很懒,什么也没写!
>下面是我上面程序运行的结果 >The producer generates a number: 1 >The consumer[1} get anumber: 1 >The producer generates a number: 2 >The consumer[1} get anumber: 2 >The producer generates a number: 3 >The consumer[2} get anumber: 3 >The producer generates a number: 4 >The consumer[1} get anumber: 4 >The producer generates a number: 5 >The consumer[2} get anumber: 5 --- 这个结果是正确的。
mgdsun2000
2009-09-07
这家伙很懒,什么也没写!
>>下面是我上面程序运行的结果 >>The producer generates a number: 1 >>The consumer[1} get anumber: 1 >>The producer generates a number: 2 >>The consumer[1} get anumber: 2 >>The producer generates a number: 3 >>The consumer[2} get anumber: 3 >>The producer generates a number: 4 >>The consumer[1} get anumber: 4 >>The producer generates a number: 5 >>The consumer[2} get anumber: 5 > >--- > > > >这个结果是正确的。 --- 为什么?线程2不是不能执行么?
bernard
2009-09-07
这家伙很懒,什么也没写!
为什么是正确的呢,仔细看代码: 生产者线程,它会生产一个,然后睡眠50 tick. 它的优先级是18。 而消费者线程,是两个,优先级分别是18和20。并且这两个线程都是运行起来后,就一直试图的去取消息,不会休眠。 那么显然就会,生产者每个50 tick生产一个,然后由两个消费者线程去消费。 50 tick才生产一个,那么肯定会导致数目不够消费者消费(两个消费者线程不主动休眠的方式消耗),所以当全部都消耗掉的时候,会如何?这两个消费者线程被挂起:假设此时是初始状态,两个线程都是READY状态,优先级18的线程获得运行,当它执行rt_sem_take(&sem_full,RT_WAITING_FOREVER); (代码第7行)这句时,因为sem_full已空,将被挂起!调度器切换到20优先级的线程继续运行,由于同样sem_full空,它也将被挂起。 当下一个数产生的时候,将先唤醒18优先级的线程(因为是FIFO方式的semaphore),再产生一个数呢? 那就应该是接下去的20优先级的线程了。
mgdsun2000
2009-09-07
这家伙很懒,什么也没写!
>为什么是正确的呢,仔细看代码: >生产者线程,它会生产一个,然后睡眠50 tick. 它的优先级是18。 > >而消费者线程,是两个,优先级分别是18和20。并且这两个线程都是运行起来后,就一直试图的去取消息,不会休眠。 > >那么显然就会,生产者每个50 tick生产一个,然后由两个消费者线程去消费。 > >50 tick才生产一个,那么肯定会导致数目不够消费者消费(两个消费者线程不主动休眠的方式消耗),所以当全部都消耗掉的时候,会如何?这两个消费者线程被挂起:假设此时是初始状态,两个线程都是READY状态,优先级18的线程获得运行,当它执行rt_sem_take(&sem_full,RT_WAITING_FOREVER); (代码第7行)这句时,因为sem_full已空,将被挂起!调度器切换到20优先级的线程继续运行,由于同样sem_full空,它也将被挂起。 > >当下一个数产生的时候,将先唤醒18优先级的线程(因为是FIFO方式的semaphore),再产生一个数呢? >那就应该是接下去的20优先级的线程了。 --- 呵呵。好像明白了。 这也就是为什么消费者1多取1次的原因吧。因为刚开始生产者、消费者1、消费者2都是READY,生产者生产出1,被消费者1取走,这时生产者休眠,消费者1也就挂起,调度器切换到20优先级的消费者2继续运行,由于同样sem_full空,它也将被挂起。这时是排队1,2。 不知道这样解释是否正确。
bernard
2009-09-07
这家伙很懒,什么也没写!
是的,基本上是这样的。
mgdsun2000
2009-09-07
这家伙很懒,什么也没写!
>是的,基本上是这样的。 --- 谢谢bernard。
撰写答案
登录
注册新账号
关注者
0
被浏览
8.2k
关于作者
mgdsun2000
这家伙很懒,什么也没写!
提问
7
回答
13
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
如何在master上的BSP中添加配置yml文件
2
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
3
RT-Thread 发布 EtherKit开源以太网硬件!
4
rt-thread使用cherryusb实现虚拟串口
5
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
14
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部