首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

一段代码,在单核/多核环境下运行,结果不一样,求高手解释!解决办法

2012-03-13 
一段代码,在单核/多核环境下运行,结果不一样,求高手解释!我测试linux(centos5.6)上面的信号是否是安全的,

一段代码,在单核/多核环境下运行,结果不一样,求高手解释!
我测试linux(centos5.6)上面的信号是否是安全的,不会丢失(哪怕cpu占用率100%的时候)。

发现一个奇怪的现象。下面一小段代码的主要功能是,创建两个计时器,定时输出一段字符串,其中第二个计时器做了一些消耗cpu的计算。我是在windows xp sp3的vbox 4.1下面安装的linux。

我发现单cpu机器运行和多cpu机器运行,结果是不一样的,这到底是为什么?
代码:

C/C++ code
#include<signal.h> #include<stdio.h> #include<stdlib.h> #include<time.h> #include<unistd.h> int count1=0,count2=0; void handler1(int sig,siginfo_t*,void*){      if(sig==SIGRTMIN){printf("Timer 1s:%d\n",++count1);} } void handler2(int sig,siginfo_t*,void*){      if(sig==SIGRTMIN+1){printf("              Timer 2s:%d\n",++count2);}      for(int i=0;i<2000000000;++i){          int j=i+2;          int k=j*j;      } } timer_t createTimer(int sig, double secs){      sigevent sev;      timer_t timerid;      sev.sigev_notify=SIGEV_SIGNAL;      sev.sigev_signo =sig;      sev.sigev_value.sival_ptr=&timerid;      if(timer_create(CLOCK_REALTIME,&sev,&timerid)==-1)return 0;            long freq_nanosecs=(long)secs*1000000000;      itimerspec its;      its.it_value.tv_sec    =freq_nanosecs/1000000000;      its.it_value.tv_nsec   =freq_nanosecs%1000000000;      its.it_interval.tv_sec =its.it_value.tv_sec;      its.it_interval.tv_nsec=its.it_value.tv_nsec;        if(timer_settime(timerid,0,&its,NULL)==-1)return 0;      return timerid; } int main(void){      struct sigaction sa;      sa.sa_flags=SA_SIGINFO;      sa.sa_sigaction=handler1;      sigemptyset(&sa.sa_mask);      if(sigaction(SIGRTMIN,&sa,NULL)==-1)return 1;      sa.sa_sigaction=handler2;      if(sigaction(SIGRTMIN+1,&sa,NULL)==-1)return 2;            createTimer(SIGRTMIN,  1);      createTimer(SIGRTMIN+1,2);      int left=10;      do{left=sleep(left);}while(left>0);      return 0; } 


运行结果和发现: 
(1)当第二个计时器没有消耗cpu的计算时(我注释掉for循环),程序的结果如我的预期: 
Timer 1s:1 
Timer 1s:2 
  Timer 2s:1 
Timer 1s:3 
Timer 1s:4 
  Timer 2s:2 
Timer 1s:5 
Timer 1s:6 
  Timer 2s:3 
Timer 1s:7 
Timer 1s:8 
  Timer 2s:4 
Timer 1s:9 
Timer 1s:10 
  Timer 2s:5 
  
(2)当for循环存在的时候,如果此时的运行环境是1个cpu,那么结果仍然是正确的。不过,每次打印之间间隔的时间变得很长了,总运行时间也远不止10s。 
(3)当for循环存在的时候,如果此时的运行环境是多个cpu(vbox可以更改cpu个数),那么结果就是非常奇怪的: 
Timer 1s:1 
Timer 1s:2 
  Timer 2s:1 
  Timer 2s:2 
  Timer 2s:3 
  Timer 2s:4 
  Timer 2s:5 
  Timer 2s:6 
  Timer 2s:7 
  Timer 2s:8 
  Timer 2s:9 
  
(4)我的初步分析: 
当机器只有一个cpu的时候,OS和进程轮流使用时间片。两个timer轮流使用cpu时间,当第二个timer在消耗cpu的时候,期间OS并没有给两个计时器增加时间,也不会通知两个计时器的事件。 
  
但是多cpu的时候,OS占用一个cpu,不断的给两个计时器计时。所以第二个timer不断的被OS提醒运行,占用了进程的所有的cpu时间,而第一个timer的计时信号则不断的被OS插入提醒列表,但是没有被响应。 
  
这也就是说明linux的行为,在cpu数量发生变化的时候,是会改变的?

[解决办法]
在aix环境下试验了一下,行为与lz的第3种情况类似

不仅第一个timer没有执行,连sleep也没有执行
看样子是全部的时间都给了timer2
可能与timer2中的for循环的执行耗时超过2s有关

信号处理程序的优先级相对较高,所以sleep得不到调度

热点排行