c++ - Sigaction 的替代方案

标签 c++ linux signals

我在 C++ 中对此类使用 sigaction 时遇到问题:

class SerialHandler{
private:
...
             
    /* Action Handling */
    struct sigaction receive_handler;
    /* Called using the receive_handler*/
    static void receive_function(int status);
    /* Get byte from the Serial Port */
    unsigned char receive_byte();
    /* Buffer for Singalinterrupt on Reciving */
    std::vector<char> in_char_buffer;
    ...
};

我确实需要使用中断,并且确实需要在中断/Sigaction 上使用成员函数 (receive_function),因为我需要访问成员变量 (vector in_char_buffer)。问题:您不能通过 sigaction 使用成员函数,因为您必须将普通函数传递给 sigaction.sa_handler。

如您所见,使用 static 函数也不是替代方法,因为您将无法访问成员变量。 wrapper 也无济于事。您将访问一个新对象,但不能访问特定对象。

那么有没有替代方案可以解决这个问题?

最佳答案

这样的事情怎么样:

#include <signal.h>
#include <string.h>

#include <vector>

using namespace std;

class SerialHandler;

// A Singleton class
class SerialHandlerManager
{
private:
    SerialHandlerManager() {};

public:
    static SerialHandlerManager* get_instance();
    void register_handler( int signum, int fd, SerialHandler * handler );

private:
    static void dispatch_signal( int signum, siginfo_t * info, void * context );

private:
    static SerialHandlerManager* the_manager;
    vector<SerialHandler *> handler_objects;
};

class SerialHandler
{
private:
    friend class SerialHandlerManager;
    void install_signal_handler( int signum )
    {
        (SerialHandlerManager::get_instance())->register_handler( signum, fd, this );
    }

    void receive_function( int status );

    int fd;     // file descriptor returned from opening the serial port
};

SerialHandlerManager* SerialHandlerManager::the_manager;

SerialHandlerManager* SerialHandlerManager::get_instance()
{
    if( !the_manager )
        the_manager = new SerialHandlerManager;
    return the_manager;
}

void SerialHandlerManager::register_handler( int signum, int fd, SerialHandler * handler )
{
    struct sigaction act;

    memset( &act, 0, sizeof(struct sigaction));

    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = SerialHandlerManager::dispatch_signal;

    handler_objects[fd] = handler;
    sigaction( signum, &act, NULL );

}

void SerialHandlerManager::dispatch_signal( int signum, siginfo_t * info, void * context )
{
    (get_instance()->handler_objects[info->si_fd])->receive_function( signum );
}

当然,您可以使用映射将文件描述符链接到对象。这绝不是全面的(或防弹的),而只是我在阅读您的问题时的一个快速想法。

祝你好运

阿尔文

关于c++ - Sigaction 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19998286/

相关文章:

c++ - 二叉搜索树插入垃圾数据

c++ - cURL CONNECTTIMEOUT 警报

linux - Shell 脚本从另一个文件循环调用函数,找不到命令。语法错误?

c++ - 如何检查哪个#define 被编译成二进制文件?

c++ - Visual Studio 中嵌套模板函数的 typeid 不一致

c++ - lambda 参数列表中的类型可以引用未捕获的外部变量吗?

c++ - 64 位 Linux 上的链接不正确

c - 使用 C 中的子进程发送和处理信号时遇到问题

c++ - "constant"GtkLabel 的 gtk+ 信号

synchronization - "S->value <= 0"signal() 在没有忙等待的信号量中实现