Windows在不同的线程中处理CTRL + C?

xx7*_*aBs 7 c++ windows qt multithreading signals

这是一个在linux和windows上处理CTRL + C信号亭的简单应用程序:

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>

void SigIntHandler()
{
    qDebug()<<"SigInt ThreadID: "<<QThread::currentThreadId();
    qApp->quit();
}

#ifdef __linux__
#include <signal.h>

    void unix_handler(int s)
    {
        //svakako je SIGINT, ali da ne javlja warning da se s ne koristi
        if (s==SIGINT)
            SigIntHandler();
    }

#else
#include <windows.h>

    BOOL WINAPI WinHandler(DWORD CEvent)
    {
        switch(CEvent)
        {
        case CTRL_C_EVENT:
            SigIntHandler();
            break;
        }
        return TRUE;
    }

#endif

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    //kod za hvatanje CTRL+C - unix i windows
    #ifdef __linux__
        signal(SIGINT, &unix_handler);
    #else
        SetConsoleCtrlHandler((PHANDLER_ROUTINE)WinHandler, TRUE);
    #endif

    qDebug()<<"Main ThreadID: "<<QThread::currentThreadId();
    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

在linux(Debian Squeeze)上编译并运行它后,我得到以下输出:

/Test-build-desktop$ ./Test 
Main ThreadID:  140105475446560 
^CSigInt ThreadID:  140105475446560 

/Test-build-desktop$ ./Test 
Main ThreadID:  140369579480864 
^CSigInt ThreadID:  140369579480864 

/Test-build-desktop$ ./Test 
Main ThreadID:  140571925509920 
^CSigInt ThreadID:  140571925509920 
Run Code Online (Sandbox Code Playgroud)

这就是我所期望的(SigIntHandler方法在主线程上运行).但是当我在Windows 7上编译并执行相同的代码时,我得到了这个:

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x5a8
SigInt ThreadID:  0x768

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x588
SigInt ThreadID:  0x1434

d:\Test-build-desktop\debug>Test.exe
Main ThreadID:  0x1170
SigInt ThreadID:  0xc38
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这里SigIntHandler方法在不同的线程中执行,然后是主...这就产生了很多问题.所以我的问题是 - 是否可以强制SigIntHandler在Windows上的主线程中运行?我可能会错误地看到siging吗?

谢谢 !!

Ale*_*x F 10

从MSDN主题HandlerRoutine:

HandlerRoutine函数是与SetConsoleCtrlHandler函数一起使用的应用程序定义函数.控制台进程使用此功能来处理进程接收的控制信号.收到信号后,系统会在进程中创建一个新线程来执行该功能.

所以,答案是:这是不可能的.

  • 事实上,微软再次以正确的方式做到了这一点.信号是Unix上最吸引人的功能之一.无需为每个函数等定义信号异步安全性.最后,在unix上的非平凡程序中,你经常最终只增加一个信号量来运行另一个可以完成实际工作的线程. (3认同)