在windows下,信号机制简单来说是通过工作线程实现的,该线程运行于相对优先级THREAD_PRIORITY_HIGHEST,当信号产生时,windows生成该线程执行信号处理逻辑,由于该线程优先级通常主线程,也高于用户自己显式创建的任何线程,windows线程调度逻辑将阻塞其余线程的执行,直到信号处理完毕工作线程退出.

以下是测试代码

#include "stdafx.h"

#include <signal.h>

#include <windows.h>

using namespace std;

int j = 1;

void OnCtrlC(int){

cout << "ctrl + c" << endl;

 cout << ::GetCurrentThreadId() << endl;

 cout <<::GetThreadPriority(::GetCurrentThread()) << endl;

signal(SIGINT,OnCtrlC);

j = 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

 signal(SIGINT,OnCtrlC);

 int  i = 0;

 

 //::SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

while(true){

  Sleep(2000);

  cout << ++ i << endl;

  cout << ::GetCurrentThreadId() << endl;

  cout <<::GetThreadPriority(::GetCurrentThread()) << endl;

//  if(j==0)

//   break;

 }

 return 0;

}

该代码可以进行两种测试

第一种:如上,该程序运行时按下Ctrl + C后将引起 OnCtrlC函数执行,这种执行可在任何时候发生,甚至在主线程cout << 100 << endl;中仅仅输出了一个10,然后执行OnCtrlC,在然后将剩下的一个0输出.程序输出表明,OnCtrlC输出的threadid 与 main输出的threadid不同,并且OnCtrlC输出的thredid不断变化,说明改函数的线程每次都是重新创建的,OnCtrlC
调用 GetThreadPriority输出为 2,正是 THREAD_PRIORITY_HIGHEST,而main输出0,为 THREAD_PRIORITY_NORMAL.

第二种,注释掉Sleep(2000),放开main中SetThreadPriority调用,放开

  if(j==0)

   break;

然后运行,这次将主线程优先级调到15,高于OnCtrlC的2,因此在程序运行中按Ctrl + C将会发现程序什么反映也没有,因为主线程的高优先级阻止OnCtrlC的执行,这也是为什么放开

  if(j==0)

   break;

的原因,假如不放开,高速的循环代码将在你注意到OnCtrlC调用之前滚屏,既然优先级高于OnCtrlC怎么又可能OnCtrlC会被调用呢?这是由于windows动态提高线程优先级机制的作用,简单来说,就是windows注意到一个线程在3--4秒一直渴望被调度时,将被暂时将优先级提高到15,这样与main优先级相等,大家不分彼此平等竞争,在程序中产生这种情况的办法是持续不断按Ctrl + C大约3秒,程序就会退出.

tip:

只所以注释掉Sleep(2000),因为Sleep函数会将自己的Cpu时间分给其他线程.

最新文章

  1. 从零点壹开始学JAVA(DAY 1 笔记)&lt;补充记录&gt;
  2. EF Fluent API上
  3. 初识Quartz(入门案例)+常用的Cron表达式
  4. php中session原理及安全性问题
  5. 我的archlinux中安装的关于xfce4的软件
  6. 支持GPS的核心API
  7. 编译caffe报错:_ZN5boost16exception_detail10bad_alloc_D2Ev
  8. mysql管理(一)
  9. 全文索引之nutch与hadoop(转)
  10. Jxl操作excel的demo
  11. 10个热门IT证书
  12. mysql函数操作(2)
  13. es6面试问题——Promise
  14. Android 测试 Appium、Robotium、monkey等框架或者工具对比
  15. jmeter 单接口测试方案(接口无业务关联)
  16. About Windows 10 SDK Preview Build 17110
  17. 集成JPA+springmvc+spring+EJB中的Java EE应用
  18. 解决bootstrap row span设置border换行的问题
  19. Matlab调用Java类
  20. Centos7下安装Docker

热门文章

  1. Django+element ui前后端不分离的博客程序
  2. 洛谷 P1194 买礼物 题解
  3. windows下powershell的包管理工具
  4. T-MAX组--项目冲刺(第五天)
  5. PHP如何解决网站大流量与高并发的问题(四)
  6. windows 下的Python虚拟环境(vitrualen)pycharm创建Django项目
  7. java/spring boot/dubbo/spring cloud/微服务/SOA/分布式经典电子书籍pdf下载
  8. 100-continue
  9. 范围指示器Extent Indicators
  10. TCP为什么会出现 RST