OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12043|回复: 11

关于rt_thread书本的二值信号量的例程疑问

[复制链接]

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
发表于 2020-11-18 10:09:10 | 显示全部楼层 |阅读模式
1金钱
创建信号量和线程.jpg 输出结果.png
创建信号量为优先级优先方式,不是FIFO方式。
receive线程优先级是3,比较低。
send线程优先级是2,比较高。
程序跑起来,receive线程会先跑到take信号量而阻塞。随后到send线程释放信号量并且继续跑到send的take信号量,这时候send的优先级比receive高,为何跑回receive来take信号量并打印Sucessful了呢?

最佳答案

查看完整内容[请看2#楼]

我知道原因了,原来是释放就马上被take走了,但因为take走的线程因为优先级不够无法调度成功,但却能take走,所以依然在高等级线程运行,当高等级线程遇到take时,但由于已经被低等级线程take走了(之前我以为低等级线程没有take成功),造成高等级线程堵塞,然后发生了调度,然后回到了已经就绪的低等级线程打印了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
 楼主| 发表于 2020-11-18 10:09:11 | 显示全部楼层
我知道原因了,原来是释放就马上被take走了,但因为take走的线程因为优先级不够无法调度成功,但却能take走,所以依然在高等级线程运行,当高等级线程遇到take时,但由于已经被低等级线程take走了(之前我以为低等级线程没有take成功),造成高等级线程堵塞,然后发生了调度,然后回到了已经就绪的低等级线程打印了。
回复

使用道具 举报

5

主题

269

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1050
金钱
1050
注册时间
2020-5-11
在线时间
252 小时
发表于 2020-11-18 13:22:41 | 显示全部楼层
本帖最后由 thisisdemo 于 2020-11-19 13:58 编辑

6666666666
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
 楼主| 发表于 2020-11-18 13:32:19 | 显示全部楼层
thisisdemo 发表于 2020-11-18 13:22
有点乱但我感觉没有问题。因为这个延时函数没有那么准确。我认为你要把释放前这句log放到获取到信号量之前 ...

打印完释放前和释放后,接着就阻塞了,但为何跑回receive里的阻塞获取信号量呢?
回复

使用道具 举报

5

主题

269

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1050
金钱
1050
注册时间
2020-5-11
在线时间
252 小时
发表于 2020-11-18 14:32:52 | 显示全部楼层
本帖最后由 thisisdemo 于 2020-11-19 13:58 编辑
lijinqiao2010 发表于 2020-11-18 13:32
打印完释放前和释放后,接着就阻塞了,但为何跑回receive里的阻塞获取信号量呢?

6666666666
1605681092(1).jpg
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
 楼主| 发表于 2020-11-18 14:48:06 | 显示全部楼层
thisisdemo 发表于 2020-11-18 14:32
我不太清除您的意思。简单说您的代码红色框内的代码片段不同时执行,那么就是没问题的。 至于其他现象, ...

输出rt_kprintf是关中断的,不会触发线程切换。延时一秒只是释放CPU权限给另一个线程或者空闲线程啊,所有第一次600,再跑一圈600就1200,那么1000肯定比1200先触发啊,那么1000后就是低优先级rceive线程进入take信号量又堵塞了,然后又回到send线程又进入了它本身的take信号,但实验打印结果显示,这时send线程在本身的take没成功,而是回到receive线程的take成功了。
回复

使用道具 举报

5

主题

269

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1050
金钱
1050
注册时间
2020-5-11
在线时间
252 小时
发表于 2020-11-18 15:51:17 | 显示全部楼层
本帖最后由 thisisdemo 于 2020-11-19 13:58 编辑
lijinqiao2010 发表于 2020-11-18 14:48
输出rt_kprintf是关中断的,不会触发线程切换。延时一秒只是释放CPU权限给另一个线程或者空闲线程啊,所 ...

6666666666
1605685535(1).jpg
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
 楼主| 发表于 2020-11-18 15:59:04 | 显示全部楼层
thisisdemo 发表于 2020-11-18 15:51
第一:我还是那个意思。只要红色区域不同时进行,那么就没问题。(我在您的log种没发现此情况)第二:这 ...

rt_printf是没关中断,但开了临界保护啊,在rt-hw_console_output里面实现,效果也类似中断那样锁死,所以打印的顺序是能正确反映程序的运行逻辑的啊。我也不明白你说红色区域不同时进行和我的疑问有什么联系,我的疑问是在同时两个线程去take信号量时,设置了优先级也按照了FIFO的形式去take了,这是我的疑问。
回复

使用道具 举报

5

主题

269

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1050
金钱
1050
注册时间
2020-5-11
在线时间
252 小时
发表于 2020-11-18 16:39:05 | 显示全部楼层
本帖最后由 thisisdemo 于 2020-11-19 13:57 编辑
lijinqiao2010 发表于 2020-11-18 15:59
rt_printf是没关中断,但开了临界保护啊,在rt-hw_console_output里面实现,效果也类似中断那样锁死,所 ...
6666666666
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2015-10-26
在线时间
8 小时
 楼主| 发表于 2020-11-18 16:58:56 | 显示全部楼层
thisisdemo 发表于 2020-11-18 16:39
第一:我一定要较个真,rt_printf在开启串口设备时候,没有执行rt-hw_console_output。!! ...

1.我的rt_printf有映射到rt_hw_console_output函数啊。
2.我知道不是这样使用,但我这样配置了,按道理线程一直会在send里运行吧,不应该跑回去打印receive的内容啊。
3.知道实验有弊端,但已经修改到这样,觉得这样的结果有疑问。另外时间片不是对相同优先级线程才有作用吗?这两个线程优先级不一样啊,立即放弃时间片?不是很明白。
回复

使用道具 举报

17

主题

237

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1312
金钱
1312
注册时间
2017-3-1
在线时间
259 小时
发表于 2021-1-5 09:26:04 | 显示全部楼层
应该是receive第一次延时内发生了调度去处理send,在send内第二次延时时,回到receive的出栈的地方重新入栈接着处理数据
回复

使用道具 举报

3

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
135
金钱
135
注册时间
2018-8-5
在线时间
11 小时
发表于 2021-11-15 18:24:42 | 显示全部楼层
优先级翻转,可以看看rtt官方文档关于互斥信号量的描述。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表