操作系统P/V操作(V操作中的典型理解偏差)

信号量是操作系统提供的⼀种协调共享资源访问的⽅法。
通常信号量表示资源的数量,对应的变量是⼀个整型( sem )变量。
另外,还有两个原⼦操作的系统调⽤函数来控制信号量的,分别是:
P 操作:将 sem 减 1 ,相减后,如果 sem < 0 ,则进程/线程进⼊阻塞等待,否则继续,表明 P操作可能会阻塞;
V 操作:将 sem 加 1 ,相加后,如果 sem <= 0 ,唤醒⼀个等待中的进程/线程,表明 V 操作不会阻塞;
P 操作是⽤在进⼊临界区之前,V 操作是⽤在离开临界区之后,这两个操作是必须成对出现的。

V原语的主要操作是

​ (1)sem加1;
​ (2)若相加结果大于零,则进程继续执行;
​ (3)若相加结果小于或等于零,则唤醒一阻塞在该信号量上的进程,然后再返回原进程继续执行或转进程调度。

典型理解偏差

  1. 以V原语的1、2步来做,Sem不就永远大于0,那进程不就一直循环执行成为死循环了?
  2. Sem大于0那就表示有临界资源可供使用,为什么不唤醒进程?
  3. Sem小于0应该是说没有临界资源可供使用,为什么还要唤醒进程?

解析

  1. P操作对sem减1的。P、V原语必须成对使用!从而不会造成死循环。
  2. Sem大于0的确表示有临界资源可供使用,而且这个时候没有进程被阻塞在这个资源上,也就是说没有进程因为得不到这类资源而阻塞,所以没有被阻塞的进程,自然不需要唤醒。
  3. V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使Sem加1,以通知其它的进程,这个时候如果Sem<0,表明有进程阻塞在该类资源上,因此要从阻塞队列里唤醒一个进程来“转手”该类资源。 比如,有2个某类资源,三个进程A、B、C、D要用该类资源,最开始Sem=2,当A进入,Sem=1,当B进入Sem=0,表明该类资源刚好用完, 当C进入时Sem=-1,表明有一个进程被阻塞了,D进入,Sem=-2。当A用完该类资源时,进行V操作,Sem=-1,释放该类资源,而这时Sem<0,表明有进程阻塞在该类资源上,于是唤醒一个。
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ATmega164P/V芯片的堆栈大小取决于其RAM容量和程序使用的栈空间。ATmega164P/V芯片的RAM容量为16KB,因此其堆栈大小理论上最大为16KB。但实际上,一部分RAM空间会被用于存储全局变量和其他数据,因此可用于堆栈的空间会相应减少。 在编写C语言程序时,我们可以通过以下两种方式来了解当前程序堆栈的大小: 1. 通过编译器提供的调试信息来查看堆栈使用情况。例如,在AVR-GCC编译器,可以使用以下编译选项来生成调试信息: ``` avr-gcc -g -o program.elf program.c ``` 通过编译后生成的ELF文件的调试信息,可以查看当前程序堆栈的大小和使用情况。 2. 在程序使用特定的方法来测试堆栈大小。例如,我们可以使用以下代码在程序运行时测试当前堆栈的最大深度: ``` #include <avr/io.h> int stack_depth = 0; void test_stack_depth() { int a = 0; stack_depth++; test_stack_depth(); } int main() { test_stack_depth(); return 0; } ``` 在这个程序,我们通过递归调用test_stack_depth()函数来不断增加堆栈的深度,直到堆栈溢出为止。运行程序后,我们可以通过查看堆栈深度来了解当前程序堆栈的大小。 需要注意的是,这种方法只是估算堆栈的大小,实际情况可能会因为代码优化等因素而有所偏差。建议在编写程序时,尽量避免使用过多的递归调用和大量的局部变量,以确保程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值