【VS开发】windows下的signal
在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时间分给其他线程.
最新文章
- 从零点壹开始学JAVA(DAY 1 笔记)<;补充记录>;
- EF Fluent API上
- 初识Quartz(入门案例)+常用的Cron表达式
- php中session原理及安全性问题
- 我的archlinux中安装的关于xfce4的软件
- 支持GPS的核心API
- 编译caffe报错:_ZN5boost16exception_detail10bad_alloc_D2Ev
- mysql管理(一)
- 全文索引之nutch与hadoop(转)
- Jxl操作excel的demo
- 10个热门IT证书
- mysql函数操作(2)
- es6面试问题——Promise
- Android 测试 Appium、Robotium、monkey等框架或者工具对比
- jmeter 单接口测试方案(接口无业务关联)
- About Windows 10 SDK Preview Build 17110
- 集成JPA+springmvc+spring+EJB中的Java EE应用
- 解决bootstrap row span设置border换行的问题
- Matlab调用Java类
- Centos7下安装Docker