• 【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 n!乘阶之和的计算 ,1!+2!+...+20!
    java 进制转换
    jquery 获取元素的绑定事件的处理代码
    java 三维数组取值
    java 计算对数函数
    js 各浏览器不兼容方法 replaceAll 解决
    SourceMap编解码原理
    如何重用浏览器tab打开页面
    npm相关知识
    关于appleScript的一些入门知识
  • 原文地址:https://www.cnblogs.com/huty/p/8517233.html
Copyright © 2020-2023  润新知