在我的C应用程序中,主进程会分叉子进程,然后休眠10微秒,让孩子有时间做好准备。在休眠期之后,父进程向子进程发送信号以开始侦听指定的端口。
此代码在CentOS6中运行良好,并且只有少数情况下,睡眠周期不足以让子进程在传送来自父进程的信号之前设置其信号处理程序。但是,当在具有相同系统规范的CentOS7中运行此代码时,孩子始终无法及时安装其信号处理程序。我不得不将睡眠时间增加到10毫秒(长1000倍),以获得与CentOS6相同的性能。
我想知道在相同规格的硬件上,CentOS 7相对于CentOS 6的上下文切换速度如此之慢可能是什么原因?
答案 0 :(得分:1)
不同编译的内核表现不同。你不能依赖时间间隔来做这些事情。由于您在父母中安装了信号处理程序,为什么不只是反转逻辑:当孩子准备就绪时,它可以向父母发送信号,然后父母可以开始控制孩子 - 没有人正忙着睡觉,一切都是事件驱动的
答案 1 :(得分:1)
进程/线程调度由OS内核决定。 CentOS 7使用的内核与CentOS 6不同。
无论如何,这根本不一定是上下文切换问题。上下文切换适用于共享相同CPU [核心]的线程/进程,但目前单核CPU很少见,至少在您期望找到CentOS的机器类上。事实上,问题可能是孩子最初是否安排在与父母相同的核心,如果是,则首先从fork()
返回。
例如,假设在CentOS 6上,孩子和父母通常最终安排(最初)在同一个核心上,孩子首先获得该核心。在这种情况下,只要孩子在第一次产生CPU之前设置了信号处理程序,父母就不会真正需要延迟。另一方面,如果在CentOS 7上,孩子通常最初安排在不同的核心上,并且两个过程立即进行,那么之前实际上并不重要的延迟突然变得重要。顺便说一下,这将是大多数措施的绩效改善。
当然,所有这些都是推测性的。主要问题是你的方法存在严重缺陷。父母不应该试图猜测孩子什么时候准备好。相反,它应该等待孩子宣布准备就绪。孩子可能通过管道或通过发信号通知父母,或者更好,他们可以通过共享信号量或互斥量(这毕竟是那些对象的用途)进行同步。