我对sched_yield
函数的问题很少,因为我发现它在我的代码中没有按预期运行。很多时候,当我尝试通过调用sched_yield
来产生它时,我看到同一个线程一次又一次地运行,即使存在其他线程。
此外,如果我有多核,对于在所有核上运行的线程,或只有一个核,sched_yield
会产生。比如说我在核心1上运行了线程1,2和3,在核心2上运行了线程4,5和6,如果从线程2调用sched_yield
,它将仅由线程1和3替换,或者1,3,4,5和6都可能吗?我问这个是因为.Net Thread.Yield
只会产生在同一个核心/处理器上运行的线程。
答案 0 :(得分:4)
http://www.kernel.org/doc/man-pages/online/pages/man2/sched_yield.2.html
sched_yield()使调用线程放弃CPU。线程是 移动到队列的末尾以获得其静态优先级并且新线程到达 运行
如果调用线程是最高优先级列表中唯一的线程 时间,它会在调用sched_yield()之后继续运行。
sched_yield不是.Net调用,并且线程/进程模型不同。 Windows / .NET的调度程序与Linux的调度程序不同。 Linux甚至有几个可能的调度程序。
所以,你对sched_yield的期望是错误的。
如果要控制线程的运行方式,可以将每个线程绑定到CPU。然后,线程将仅在绑定的CPU上运行。如果你有几个绑定到同一个CPU的线程,则使用sched_yield MAY 切换到另一个绑定到当前CPU并准备运行的线程。
如果每个线程都想要进行大量的CPU密集型工作,那么每个CPU使用多个线程也是不错的主意。
如果要完全控制,如何运行线程,可以使用RealTime线程。 http://www.linuxjournal.com/magazine/real-time-linux-kernel-scheduler - SCHED_FIFO和SCHED_RR RT政策。
答案 1 :(得分:-5)
为什么要放弃CPU?嗯......
我正在修复客户端代码中的错误。基本上,他们有一个包含信息的共享结构:
以上是在流程A中。其余代码正在流程B中。流程B向流程A发送消息以计算并在托管中返还货币(这是自动售货机)。没有进入为什么代码以这种方式编写的历史,原始代码序列是:
(流程B) 将消息RETURN_ESCROWED_BILLS发送到进程A. 发送消息RETURN_ESCROWED COINS到进程A. 将共同结构清零
执行如下:
(流程B): 发送消息; 把结构归零;
(稍后......流程A): 得到消息; common struct中的所有字段都是0; 无事可做;
哎呀......钱还在托管,但过程A代码已经失去了知识。真正需要的是(除了大规模重构代码之外):(流程B): 发送消息; 产生CPU;
(过程A): 确定托管款项和退货; 产生CPU; (可能只是到了时间片的末尾,不需要特殊的方法)
(流程B): 将常见结构清零;
任何时候你有IPC消息,并且发送/接收消息的进程紧密耦合。 最佳方式是进行双向握手。但是,有些情况(通常由于设计不佳或不存在而导致)必须紧密耦合真正应该松散耦合的进程。 通常 CPU的产量是一个黑客,因为你没有选择。增加多核CPU是一个痛苦的根源,特别是从单核移植到多核时。