热门关键字:  ubuntu  分区  函数  linux系统进程  Fedora

当前位置 :| 主页>Linux教程>编程开发>C++>

由一个进程的等待引起的思考

来源: 作者: 时间:2008-07-03 Tag: 点击:
今天,在写网卡状态检测的时候,用到了睡眠与唤醒.基本式样如下所示:

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就永远失去了被调度的机会.
上一篇:C笔试题
下一篇:c code stytle
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
栏目列表