2015-09-04 251 views
3

我正試圖將端口caffe(開發用於Linux)的源代碼移植到Windows環境中。問題是sigaction結構在signal_handler.cppsignal_handler.h。源代碼如下所示。 我的查詢是可以完成的庫或代碼替換,以使sigaction在Windows中工作。Sigaction並將Linux代碼移植到Windows

///頭文件

#ifndef INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_ 
#define INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_ 

#include "caffe/proto/caffe.pb.h" 
#include "caffe/solver.hpp" 

namespace caffe { 

class SignalHandler { 
public: 
    // Contructor. Specify what action to take when a signal is received. 
    SignalHandler(SolverAction::Enum SIGINT_action, 
       SolverAction::Enum SIGHUP_action); 
    ~SignalHandler(); 
    ActionCallback GetActionFunction(); 
private: 
    SolverAction::Enum CheckForSignals() const; 
    SolverAction::Enum SIGINT_action_; 
    SolverAction::Enum SIGHUP_action_; 
}; 

} // namespace caffe 

#endif // INCLUDE_CAFFE_UTIL_SIGNAL_HANDLER_H_ 

///源文件

#include <boost/bind.hpp> 
    #include <glog/logging.h> 

    #include <signal.h> 
    #include <csignal> 

    #include "caffe/util/signal_handler.h" 

    namespace { 
     static volatile sig_atomic_t got_sigint = false; 
     static volatile sig_atomic_t got_sighup = false; 
     static bool already_hooked_up = false; 

     void handle_signal(int signal) { 
     switch (signal) { 
     case SIGHUP: 
      got_sighup = true; 
      break; 
     case SIGINT: 
      got_sigint = true; 
      break; 
     } 
     } 

     void HookupHandler() { 
     if (already_hooked_up) { 
      LOG(FATAL) << "Tried to hookup signal handlers more than once."; 
     } 
     already_hooked_up = true; 

     struct sigaction sa; 
     // Setup the handler 
     sa.sa_handler = &handle_signal; 
     // Restart the system call, if at all possible 
     sa.sa_flags = SA_RESTART; 
     // Block every signal during the handler 
     sigfillset(&sa.sa_mask); 
     // Intercept SIGHUP and SIGINT 
     if (sigaction(SIGHUP, &sa, NULL) == -1) { 
      LOG(FATAL) << "Cannot install SIGHUP handler."; 
     } 
     if (sigaction(SIGINT, &sa, NULL) == -1) { 
      LOG(FATAL) << "Cannot install SIGINT handler."; 
     } 
     } 

     // Set the signal handlers to the default. 
     void UnhookHandler() { 
     if (already_hooked_up) { 
      struct sigaction sa; 
      // Setup the sighub handler 
      sa.sa_handler = SIG_DFL; 
      // Restart the system call, if at all possible 
      sa.sa_flags = SA_RESTART; 
      // Block every signal during the handler 
      sigfillset(&sa.sa_mask); 
      // Intercept SIGHUP and SIGINT 
      if (sigaction(SIGHUP, &sa, NULL) == -1) { 
      LOG(FATAL) << "Cannot uninstall SIGHUP handler."; 
      } 
      if (sigaction(SIGINT, &sa, NULL) == -1) { 
      LOG(FATAL) << "Cannot uninstall SIGINT handler."; 
      } 

      already_hooked_up = false; 
     } 
     } 

     // Return true iff a SIGINT has been received since the last time this 
     // function was called. 
     bool GotSIGINT() { 
     bool result = got_sigint; 
     got_sigint = false; 
     return result; 
     } 

     // Return true iff a SIGHUP has been received since the last time this 
     // function was called. 
     bool GotSIGHUP() { 
     bool result = got_sighup; 
     got_sighup = false; 
     return result; 
     } 
    } // namespace 

    namespace caffe { 

    SignalHandler::SignalHandler(SolverAction::Enum SIGINT_action, 
           SolverAction::Enum SIGHUP_action): 
     SIGINT_action_(SIGINT_action), 
     SIGHUP_action_(SIGHUP_action) { 
     HookupHandler(); 
    } 

    SignalHandler::~SignalHandler() { 
     UnhookHandler(); 
    } 

    SolverAction::Enum SignalHandler::CheckForSignals() const { 
     if (GotSIGHUP()) { 
     return SIGHUP_action_; 
     } 
     if (GotSIGINT()) { 
     return SIGINT_action_; 
     } 
     return SolverAction::NONE; 
    } 

    // Return the function that the solver can use to find out if a snapshot or 
    // early exit is being requested. 
    ActionCallback SignalHandler::GetActionFunction() { 
     return boost::bind(&SignalHandler::CheckForSignals, this); 
    } 

    } // namespace caffe 

的錯誤是

.\src\caffe\util\signal_handler.cpp(39): error C2065: 'SIGHUP' : undeclared identifier 
1>..\src\caffe\util\signal_handler.cpp(42): error C2514: '`anonymous-namespace'::HookupHandler::sigaction' : class has no constructors 
1>   ..\src\caffe\util\signal_handler.cpp(31) : see declaration of '`anonymous-namespace'::HookupHandler::sigaction' 
1>..\src\caffe\util\signal_handler.cpp(50): error C2079: 'sa' uses undefined struct '`anonymous-namespace'::UnhookHandler::sigaction' 
1>..\src\caffe\util\signal_handler.cpp(52): error C2228: left of '.sa_handler' must have class/struct/union 
1>   type is 'int' 
1>..\src\caffe\util\signal_handler.cpp(54): error C2228: left of '.sa_flags' must have class/struct/union 
1>   type is 'int' 
1>..\src\caffe\util\signal_handler.cpp(54): error C2065: 'SA_RESTART' : undeclared identifier 
1>..\src\caffe\util\signal_handler.cpp(56): error C2228: left of '.sa_mask' must have class/struct/union 
+0

如果仍然相關,下面GitHub庫端口來自Caffe到Windows:https://github.com/happynear/caffe-windows – rkellerm

+0

有一個ANSI C信號()函數可能處理你想要的中斷。你想要的常量在signal.h中,或者C++中的。 – seattlecpp

回答

6

sigaction是UNIX的一部分信號API。 Windows僅提供signal,不支持SIGHUP或任何標誌(如SA_RESTART)。但是,非常基本的支持仍然存在,所以如果您只使用signal(而不是sigaction),代碼仍然可以正常工作。

+0

我無法替換sigaction。但是,我可以替換功能,我的意思是由sigaction支持的操作將被信號替換。信號在Windows中提供。你怎麼想? – batuman

+0

是的,目前的解決方案只是將sigaction功能註釋掉,因爲我目前沒有時間解決。 Windows不提供SIGHUP標誌,我將用Windows支持並且有用的標誌替換。 – batuman

2

基於@nneonneo:

void handle_signal(int signal) { 
    switch (signal) { 
#ifdef _WIN32 
    case SIGTERM: 
    case SIGABRT: 
    case SIGBREAK: 
#else 
    case SIGHUP: 
#endif 
     got_sighup = true; 
     break; 
    case SIGINT: 
     got_sigint = true; 
     break; 
    } 
    } 
void HookupHandler() { 
    if (already_hooked_up) { 
     LOG(FATAL) << "Tried to hookup signal handlers more than once."; 
    } 
    already_hooked_up = true; 
#ifdef _WIN32 
    signal(SIGINT, handle_signal); 
    signal(SIGTERM, handle_signal); 
    signal(SIGABRT, handle_signal); 
#else 
    struct sigaction sa; 
    // Setup the handler 
    sa.sa_handler = &handle_signal; 
    // Restart the system call, if at all possible 
    sa.sa_flags = SA_RESTART; 
    // Block every signal during the handler 
    sigfillset(&sa.sa_mask); 
    // Intercept SIGHUP and SIGINT 
    if (sigaction(SIGHUP, &sa, NULL) == -1) { 
     LOG(FATAL) << "Cannot install SIGHUP handler."; 
    } 
    if (sigaction(SIGINT, &sa, NULL) == -1) { 
     LOG(FATAL) << "Cannot install SIGINT handler."; 
    } 
#endif 
    } 
void UnhookHandler() { 
    if (already_hooked_up) { 
#ifdef _WIN32 
     signal(SIGINT, SIG_DFL); 
     signal(SIGTERM, SIG_DFL); 
     signal(SIGABRT, SIG_DFL); 
#else 
     struct sigaction sa; 
     // Setup the sighub handler 
     sa.sa_handler = SIG_DFL; 
     // Restart the system call, if at all possible 
     sa.sa_flags = SA_RESTART; 
     // Block every signal during the handler 
     sigfillset(&sa.sa_mask); 
     // Intercept SIGHUP and SIGINT 
     if (sigaction(SIGHUP, &sa, NULL) == -1) { 
     LOG(FATAL) << "Cannot uninstall SIGHUP handler."; 
     } 
     if (sigaction(SIGINT, &sa, NULL) == -1) { 
     LOG(FATAL) << "Cannot uninstall SIGINT handler."; 
     } 
#endif 

     already_hooked_up = false; 
    } 
    }