回应控制台应用程序中的问题(Linux)

时间:2009-07-21 08:13:07

标签: c++ linux console

我在控制台应用程序中遇到一个奇怪的问题。

首先,代码片段:

的main.cpp

#include "DebugInterface.h"

static sigset_t signalSet;
static pthread_t CleanupHandlerThread;
DebugInterface* debugInterface = NULL;

void* CleanupHandler (void* param) {
    int32_t sig, err;
    err = sigwait (&signalSet, &sig);

    delete debugInterface;
    debugInterface = NULL;
    exit (EXIT_SUCCESS);

    return NULL;
}

int32_t main(int32_t argc, char** argv) {
    sigemptyset (&signalSet);
    sigaddset (&signalSet, SIGINT);
    pthread_sigmask (SIG_BLOCK, &signalSet, NULL);
    pthread_create (&CleanupHandlerThread, NULL, CleanupHandler, NULL);

    debugInterface = new DebugInterface();

    if (debugInterface != NULL) {
        debugInterface->StartReading();
    }

    while (true) {
        // Core functionality follows, but was commented out
        // (was not relevant for problem, checked it -
        // you may even remove this loop completely)
    }

    return EXIT_SUCCESS;
}

DebugInterface.h

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <iomanip>
#include <readline/readline.h>
#include <readline/history.h>
#include <signal.h>

class DebugInterface {
public:
    DebugInterface() { }
    virtual ~DebugInterface() { }

private:
    pthread_t ConsoleHandlerThread;

private:
    static void* ConsoleHandler (void* param);

public:
    bool StartReading();
};

DebugInterface.cpp

#include "DebugInterface.h"

void* DebugInterface::ConsoleHandler (void* param) {
    while (true) {
        char* input = readline ("\n> ");

        // Handle input, was commented out, too (irrelevant for problem)

        free (input);
    }

    return NULL;
}

bool DebugInterface::StartReading() {
    if (pthread_create (&ConsoleHandlerThread, NULL, DebugInterface::ConsoleHandler, NULL) != 0) {
        return false;
    }
    return true;
}

代码运行正常并且符合预期,但是当它通过捕获信号SIGINT退出并终止时,控制台输出后来被隐藏(即控制台/终端的行为类似于应用命令“stty -echo”)。

我已经插入了代码'system(“stty echo”);'在退出之前的函数CleanupHandler中它“解决”了问题,但这不是正确的解决方案......也许我错过了一个没有出现的严重错误。我还没弄清楚我的代码在终止后如何影响控制台输出/终端本身,因为没有任何系统调用/函数调用可能会改变控制台行为(我只使用“printf”和颜色格式化控制台输出)。

上面的代码片段应该重现问题,编译器/链接器配置和输出是:

make all 
Building file: ../main.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
Finished building: ../main.cpp

Building target: Testproject
Invoking: GCC C++ Linker
g++  -o"Testproject"  ./DebugInterface.o ./main.o   -lreadline -lpthread
Finished building target: Testproject

我正在服务器上进行远程开发,问题就是通过这种方式和SSH进行,所以这不是任何控制台错误。此外,将控制台输入处理程序放在主线程中并将子线程中的核心功能/循环放在一起并没有什么区别。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

接收信号时,您的程序没有完全终止。原因是readline库。

检查readline文档中有关信号处理的内容here

答案 1 :(得分:1)

运行strace下的代码,您可能会发现终端输出的确切位置。

答案 2 :(得分:0)

谢谢,根据GNU Readline Library添加了两个清理函数解决了这个问题。

您必须在表达式“delete debugInterface;”之前添加以下函数:

rl_cleanup_after_signal();
rl_free_line_state();

[...]

delete debugInterface;