从 C++ 中的 posix 信号处理程序获取对象属性

Posted

技术标签:

【中文标题】从 C++ 中的 posix 信号处理程序获取对象属性【英文标题】:get object properties from posix signal handler in C++ 【发布时间】:2012-06-04 05:59:32 【问题描述】:

我正在尝试让信号处理程序在 C++ 中工作,但不知道如何使用某些类属性。

信号处理程序在收到 SIGIO 信号时触发,我需要检查它是否用于正确的套接字。

我需要做的就是能够访问私人socket_ 和公共received()

namespace sigh 

 template<typename SomeType>
 class WorkWithSignals
 
 public:
   void received( unsigned char* data, size_t len, unsigned int from );

 private:
   static void sigio_handler ( int sig, siginfo_t* siginfo, void* empty );
   int socket_;
 ;

 extern "C" 
   void sigio_handler ( int sig, siginfo_t* siginfo, void* empty ) 
      if (siginfo->si_fd == ***socket_*** )
        ***received*** ();
   
 


除此之外,我尝试在sigio_handler 的定义之前定义一个静态结构变量,将其填充到sigio_handler 之后定义的类构造函数中,但sigio_handler 抱怨它不在范围内。

任何指针?

【问题讨论】:

与您的问题无关,但信号处理程序不必是extern "C" 【参考方案1】:

您不能从静态方法访问成员变量(只是没有对象)。您也可以将socket_ 设为静态变量,并通过WorkWithSignals&lt;...&gt;::socket_ 引用它。

【讨论】:

【参考方案2】:

信号处理程序是一个静态方法,因此它不会绑定到您的类的任何实例。

sigaction 手册页包含段落​​(与 siginfo_t 参数有关):

   * SIGPOLL/SIGIO fills in si_band and si_fd.  The si_band event is a bit
     mask containing the same values as are filled in the revents field by
     poll(2).  The si_fd field indicates the file descriptor for which the
     I/O event occurred.

假设您想继续当前基于信号的设计(poll() 可能更容易),我建议将文件描述符静态映射到 WorkWithSignals 类的实例。

然后在静态信号处理程序中,查找与给定文件描述符(您的 socket_ 字段)相关的实例,然后调用非静态方法对特定对象执行所需的工作。

在 WorkWithSignals 的声明中添加

static std::map<int, WorkWithSignals*> object_registry_;

以及源文件中所需的def。通过在注册信号处理程序之前添加到地图并在销毁对象之前从地图中删除来管理地图中的成员资格。那么:

   void sigio_handler ( int sig, siginfo_t* siginfo, void* empty ) 
      std::map<int, WorkWithSignals*>::iterator it = object_registry_.find(siginfo->si_fd);
      if(it == object_registry_.end())
          // handle error case
          assert(false);

      // Check that si_band is masked with the read flag as in the poll() call (look for revents)
      WorkWithSignals* obj = it->second;
      obj->received();
   

【讨论】:

以上是关于从 C++ 中的 posix 信号处理程序获取对象属性的主要内容,如果未能解决你的问题,请参考以下文章

c++中的Posix线程

linux 平台上 C# 中的自定义 posix 信号不起作用

C++中的POSIX线程编程

如何从 C++ 中的 tm 对象获取星期几?

在 posix 线程上创建自动释放池

如何使用 C++ 代码中的 BTRFS 写入时复制?