免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: tomkedy
打印 上一主题 下一主题

关于抢占的问题 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2011-07-02 01:14 |只看该作者
回复 18# ruslin
进程基本的是三个状态,run,ready,wait。进入run状态表明占用CPU。可抢占的话A进入ready状态。
具体看内核代码吧,那个很直观

论坛徽章:
0
22 [报告]
发表于 2011-07-02 01:23 |只看该作者
回复  vupiggy


如果你是高手你肯定明白几句话就要讲清楚内核抢占给不太了解内核的人来说是非常困难的 ...
ruslin 发表于 2011-07-01 09:29

哎呦,您知道内核态抢占耶,高手,高手,高高手。

但是... ... 您哪只眼看见他们上面讨论内核态抢占的问题了?您确定您明白楼主在问什么以及上面他们在讨论什么吗?您就继续感觉良好吧您。

论坛徽章:
0
23 [报告]
发表于 2011-07-02 01:24 |只看该作者
顺便说一声,``为什么删我帖''童鞋的回答大抵正确,楼主理解不了就要自己看书啃源码去了,别人帮不了。

论坛徽章:
0
24 [报告]
发表于 2011-07-02 16:18 |只看该作者
本帖最后由 ruslin 于 2011-07-02 16:39 编辑

回复 21# jack4010


    慎重回答,参考ulk3 第3章
linux进程不区分 正在cpu上执行和准备执行状态。都是TASK_RUNNING
正是因为TASK_RUNNING得进程数大于cpu个数,才有抢占这回事

论坛徽章:
0
25 [报告]
发表于 2011-07-02 16:54 |只看该作者
顺便说一声,``为什么删我帖''童鞋的回答大抵正确,楼主理解不了就要自己看书啃源码去了,别人帮不了。
vupiggy 发表于 2011-07-02 01:24


vupiggy,

谢谢你的回复,对于“为什么删我帖“的回答我已作了回复,详细在 第13楼,vupiggy兄有空的话也可以点评下,但希望是平心静气的技术探讨,这样也可以使更多有兴趣的人参与到讨论中来..........

论坛徽章:
0
26 [报告]
发表于 2011-07-03 02:08 |只看该作者
对于“为什么删我帖“的回答我已作了回复
tomkedy 发表于 2011-07-02 09:54


还真把那狗屁不通的回复当回事,好一个外恭内倨的小盆友。

知道为啥``为什么删我贴''不再回贴做解释吗?你连基本的概念都不清楚,怎么讨
论得下去?最致命的还不在于此,而在你对于他人的回复压根没有意愿去查证,去
深挖核实其合理性。相反地,你总是直觉地,非常主观地从脑袋里蹦出一些概念和
逻辑来反驳。自说自话非常惹人厌啊。

Read The Fxxking Code!而不是在脑袋里玩弄那些含混不清的概念,还觉得自
己理解得挺透彻。从那个自旋锁的帖子就可以看出来,你根本就不爱读代码理解代码,
叫别人怎么跟你讨论?

这样吧,解释一下为什么说你13楼的回复狗屁不通,省得小盆友不服气。

我觉得如果进程A在创建进程B的最后阶段不进行一次调度处理,则内核是不会知道
进程B的优先级高于进程A从而实现方案1的
tomkedy 发表于 2011-06-30 06:29

你觉得?你觉得进程 A 不通过内核怎么有能力自己创建进程 B?这是不是最基本
的常识?既然创建进程需要通过内核,如果新创建的进程优先级更高,内核怎么会
不知道?事实上,Linux 进程模型的实现是把子进程挂在父进程所在优先级的 run
queue 上,代码调用的层次大概是:do_fork() 先调用 copy_process() 复制一份
进程描述子为子,进行一系列初始化之后,最终会调到   wake_up_new_task(),这
个函数负责把子进程挂到适当的 run queue 上。

(但个人认为创建进程一般是不需要再进行进程调度的)......
tomkedy 发表于 2011-06-30 06:29


你认为?认为个屁。如果您肯屈尊区读一下 Linux 的代码就知道,如果不复制 VM,
内核让子进程先运行,为了避免可能不必要的 Copy On Write。看函数
wake_up_new_task():

  1. if (!(clone_flags & CLONE_VM)) {
  2.         /*
  3.          * The VM isn't cloned, so we're in a good position to
  4.          * do child-runs-first in anticipation of an exec. This
  5.          * usually avoids a lot of COW overhead.
  6.          */
  7.         if (unlikely(!current->array))
  8.                 __activate_task(p, rq);
  9.         else {
  10.                 p->prio = current->prio;
  11.                 p->normal_prio = current->normal_prio;
  12.                 list_add_tail(&p->run_list, &current->run_list);
  13.                 p->array = current->array;
  14.                 p->array->nr_active++;
  15.                 inc_nr_running(p, rq);
  16.         }
  17.         set_need_resched();
  18. }
复制代码
看见那个 list_add_tail() 了吗,子进程被插到父进程前面去鸟。

稍微解释一下set_new_resched(); 进程进入内核(经由中断,系统调用)之后,执行完服
务例程,回到刚才被中断的运行点之前,都要检查一下进程的   TIF_NEED_RESCHED
标志,如果被置就要调用 schedule(),看 arch/x86_64/kernel/entry.S,作为系
统调用的例子,去除不重要的细节,在返回用户空间继续执行之前:

  1. sysret_check:               
  2.         GET_THREAD_INFO(%rcx)
  3.         cli
  4.         ...
  5.         movl threadinfo_flags(%rcx),%edx
  6. ...
  7. sysret_careful:
  8.         ...
  9.         bt $TIF_NEED_RESCHED,%edx
  10.         call schedule
  11.         ...
复制代码
有木有调度一次,有木有?骂你不冤吧?

对于你的方案二,如果进程A占用的只是一个共享的变量,那释放它也要一次调度?
tomkedy 发表于 2011-06-30 06:29


释放?你确信你了解``释放''的含义?你以为进程访问完资源以后悄无声息地离开
就叫做释放?如果这事儿真发生鸟,只能说明这部分负责共享资源的同步代码有大
虫子了。释放必然伴随一个唤醒过程,或唤醒一个指定(阻塞在该资源上的)进程,
或唤醒一整个      wait     queue。阻塞的进程一般都是通过将进程状态指定为
TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE,然后调 schedule(),在这个函数
里进程被从  run  queue  上拎走,如果没有其它代码显式地唤醒它重新把它挂入
run queue,这个进程就不可能再有任何机会运行了。

看 try_to_wake_up() 最后部分代码,这是一次抢占可能发生的场景:

  1. out_running:
  2.         trace_sched_wakeup(p, success);
  3.         check_preempt_curr(rq, p, wake_flags);
  4. ...
复制代码
再看 check_preempt_curr() CFS的实现(sched_fair.c) 最后那一段:

  1. preempt:
  2.         resched_task(curr);
复制代码
于是 run queue 的首(curr)进程,回到 entry.S 中的汇编代码部分就会发现
TIF_NEED_RESCHED 被设置于是调用 schedule,呼唤调度器,抢占发生。

要是你对``为什么删你贴''的回复真以为意,继而进入内核源码去求证,你还会有
那些古怪的疑问吗?你压根就不想去看代码,自以为概念清晰,自说自话。

要不是71有一天假,谁有时间搁这废话,你继续玩儿好,以后少陪鸟。

论坛徽章:
0
27 [报告]
发表于 2011-07-03 02:13 |只看该作者
这样的问题都不应该发到这 C/C++ 版,隔壁内核源码版才是这贴应该的去处,而且那里的版主超 nice

论坛徽章:
0
28 [报告]
发表于 2011-07-03 20:37 |只看该作者
本帖最后由 tomkedy 于 2011-07-03 20:44 编辑

vupiggy,

谢谢你的回复,我的看法如下:

你觉得?你觉得进程 A 不通过内核怎么有能力自己创建进程 B?这是不是最基本
的常识?既然创建进程需要通过内核,如果新创建的进程优先级更高,内核怎么会
不知道?事实上,Linux 进程模型的实现是把子进程挂在父进程所在优先级的 run
queue 上,代码调用的层次大概是:do_fork() 先调用 copy_process() 复制一份
进程描述子为子,进行一系列初始化之后,最终会调到   wake_up_new_task(),这
个函数负责把子进程挂到适当的 run queue 上。
vupiggy 发表于 2011-07-03 02:08

  
fork一个子进程的过程当然要内核参与,内核当然知道有关父进程和子进程的所有“信息”(当然包括A和B的优先级值)。但如果要选择一个进程来运行,则(一般来说)内核会对所有的就绪进程的优先级进程比较,选择优先级最高的先运行,而这项遍历-比较-选择(简写)的过程是由调度函数实现的。因此,我说“我觉得如果进程A在创建进程B的最后阶段不进行一次调度处理,则内核是不会知道进程B的优先级高于进程A从而实现方案1的”。  



你认为?认为个屁。如果您肯屈尊区读一下 Linux 的代码就知道,如果不复制 VM,
内核让子进程先运行,为了避免可能不必要的 Copy On Write。看函数
wake_up_new_task():
vupiggy 发表于 2011-07-03 02:08

   
这是linux的做法,不代表所有操作系统都会让子进程先运行,因此不见得所有操作系统都要在fork的末尾都要进程调度......


释放?你确信你了解``释放''的含义?你以为进程访问完资源以后悄无声息地离开
就叫做释放?如果这事儿真发生鸟,只能说明这部分负责共享资源的同步代码有大
虫子了。释放必然伴随一个唤醒过程,或唤醒一个指定(阻塞在该资源上的)进程,
或唤醒一整个      wait     queue。阻塞的进程一般都是通过将进程状态指定为
TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE,然后调 schedule(),在这个函数
里进程被从  run  queue  上拎走,如果没有其它代码显式地唤醒它重新把它挂入
run queue,这个进程就不可能再有任何机会运行了。
vupiggy 发表于 2011-07-03 02:08

   
对于某些共享资源的管理,如:管程,是需要像你所说的在“释放”之后,需要“唤醒“潜在等待的进程;而对于其他的一些同步管理的方法,如“自旋锁“,就不需要“唤醒”操作。如果进程在临界区里需要执行较长时间,则采用前一种方法较合适,让等待的进程都先阻塞,以节省CPU周期;但如果进程只需要在临界区里执行很短时间(如我的例子,只有一个共享变量),则采用忙等待的方式较合算(相对于各个等待进程的切换开销)。


Read The Fxxking Code!而不是在脑袋里玩弄那些含混不清的概念,还觉得自
己理解得挺透彻。从那个自旋锁的帖子就可以看出来,你根本就不爱读代码理解代码,
叫别人怎么跟你讨论?
vupiggy 发表于 2011-07-03 02:08


我不是不愿意看代码,但操作系统并不只有linux,看问题不应只局限在linux上,虽然linux也是个相当出色的操作系统(个人看法)......

论坛徽章:
0
29 [报告]
发表于 2011-07-04 02:23 |只看该作者
你确信你还清楚你在讨论什么?B如果在等待自旋锁就已经是运行态了,谈何在哪个时间点进入就绪态?

有点哭笑不得,这小伙子前两天连几行自旋锁实现的代码都看不明白,怎么就信心爆棚一本正经地教育起别人自旋锁来了。哎,这业界夸夸其谈,眼高手低,纸上谈兵的可是真不少。假期结束,恕我失陪,happy hacking, oh no, happy talking!

论坛徽章:
0
30 [报告]
发表于 2011-07-04 06:40 |只看该作者
你确信你还清楚你在讨论什么?B如果在等待自旋锁就已经是运行态了,谈何在哪个时间点进入就绪态?

有点哭 ...
vupiggy 发表于 2011-07-04 02:23


vupiggy,

谢谢你的回复。请再重看11楼,13楼,28楼的回复...........
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP