Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2762155
  • 博文数量: 79
  • 博客积分: 30130
  • 博客等级: 大将
  • 技术积分: 2608
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-22 14:58
个人简介

博所搬至http://xiaogr.com

文章存档

2015年(2)

2009年(3)

2008年(56)

2007年(18)

分类: LINUX

2008-07-01 18:07:42

今天,在写网卡状态检测的时候,用到了睡眠与唤醒.基本式样如下所示:
 
A: A是一个等待进程.等待condition 满足过后退出死循环.
A:
 ......
 while(1)
 {
  if ( condition )  //条件成立了
   goto: OUT
  else{
   //1:----------------------
   set_current_state(TASK_UNINTERRUPTIBLE);
   schedule();
   set_current_state(TASK_RUNNING);
  }  
 }
OUT:
 ......
B进程会唤醒A进程:
B:
 ......
 wake_up_process(A)
 
 
写完之后,虽然测试通过了```但是老感觉有什么问题.所下:
在A进程中,首先它判断条件不满足,然后进入到else中.如果运行到1:------的时候.B进程被抢占进来了`并将A唤醒```
之后.A进程被调度回CPU.然后沿着1:------以下的部份运行,它设置当前状态,自己调用schedule().错过了这次条件````此后.A就会被移出运行队列,永远都睡眠着```
 
我开始怀疑这段代码,搜索了内核代码,发现内核中很多地方也有相类似的用法.无奈之下,向"中文邮件列表"中的众位高手请教,终于发现了问题所在.正确的写法应该是这样的:
                    //1:----------------------//
                     set_current_state(TASK_UNINTERRUPTIBLE);
                     if (!condition)
                               schedule();
                         set_current_state(TASK_RUNNING);
                
真是差之毫里,失之千里.现把这两段代码分析一下.
 
在第一段代码中.如果在标号处被抢占,B调用 wake_up_process(A)将A唤醒,此时A的运行状态会设为TASK_RUNNING.如切换到A进程运行时,之后的代码又会将其设为TASK_UNINTERRUPTIBLE.
在调用schdule()的时候,会判断进程是自愿放弃CPU还是被抢占出来的,如果是自愿放弃且进程不为运行状态.就会将其从运行队列中删除.
这样.A就永远失去了被调度的机会.
 
在第二种情况中:
1:进程A在set_current_state(TASK_UNINTERRUPTIBLE);之前被抢占,B将其唤配,切换回A后,判断condition条件时,会是一个真值,之后又会被调会TASK_RUNNING.这是正常的.
2:进程A在set_current_state(TASK_UNINTERRUPTIBLE)之后被抢占,假设抢占地在判断完条件之后.这样在B中会将A设为RUNING状态,A切换回来的时候,进入到schdule()后不会被踢出运行队列,只是等待下次调度而已,这也是正常的.
 
今天幸好有高人指点迷津```看来以后学习还是要多动脑子!
阅读(4812) | 评论(6) | 转发(1) |
0

上一篇:求开源项目```

下一篇:Linux文件系统之sysfs

给主人留下些什么吧!~~

xgr1802008-08-13 10:35:55

这两个地方的condition是一样,不同的是之前的代码被抢占后无非被唤回。 之后的代码,被抢占后还是正常的。。。

xgr1802008-08-13 10:35:55

这两个地方的condition是一样,不同的是之前的代码被抢占后无非被唤回。 之后的代码,被抢占后还是正常的。。。

xgr1802008-08-13 10:35:55

这两个地方的condition是一样,不同的是之前的代码被抢占后无非被唤回。 之后的代码,被抢占后还是正常的。。。

chinaunix网友2008-08-12 15:14:00

两段代码中的两个 condition 应该是不同的吧!?

chinaunix网友2008-08-12 15:14:00

两段代码中的两个 condition 应该是不同的吧!?