我正在尝试构建一个多线程程序,它将创建Child
和"运行"的四个实例。一套昂贵的" Job
秒。父母将发送一个信号,表明他们什么时候开始。现在,每个子线程必须捕获该信号。它内部有一个sig_handler
。它是Child
内的私人课程。
到目前为止,我把它定义为:
private:
class sig_handler {
typedef struct sigaction sigAct;
Shared* sh;
//============
void whatSig();
public:
sig_handler( Shared* s );
sigAct action;
sigset_t signalset; // Just want siguser and sigquit
static void catchSig( int sig ); // interacts with the shared resource
// it starts up the threads
};
首先,将类作为信号处理程序是否可以?如果没问题(这肯定会使可读性更好),我们将如何实现它?
我试图捕捉SIGUSR1
,以便我可以更改Shared
内存中的标记。每个线程都可以通过指向此对象的指针访问Shared
内存,即Shared* share
。这是使用类来充当一种共享基础。
现在这是我真正需要回答的问题。我开始设置我的sigset_t signalSet
:
Child::sig_handler::sig_handler( Shared* s ) {
sh = s;
sigemptyset(&signalset);
sigaddset(&signalset, SIGUSR1); // Add these to the now empty set
sigaddset(&signalset, SIGQUIT);
action.sa_handler = catchSig; // 1
action.sa_mask = signalset;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, NULL); // attach the class member action
}
真正关注第1行。这是一个关键点。我认为这必须是一个静态或全局的功能。这是可能发生错误的地方。当我使我的类方法catchSig(int sig)
非静态时,第1行会抱怨Reference to a non-static function call must be called
。当发生这种情况时,我将其定义为:void catchSig( int sig );
当我将其定义为static void catchSig( int sig );
时,编译器会在第2行抱怨。
void Child::sig_handler::catchSig(int sig) {
sh->startflag; // 2
}
它说,Invalid use of 'sh' in static member function
。我需要能够访问此变量。如何解决这个问题,以便我可以获得sig_handler
课程,并通过catchSig()
分享?
我实施了StoryTeller关于使用指针this
的建议。虽然它可以阻止编译器的抱怨,但我仍然有构建时错误。我将sig_handler
的定义改为现在为止:
private:
class sig_handler {
typedef struct sigaction sigAct;
Shared* sh;
static sig_handler* self;
//============
void whatSig();
public:
sig_handler( Shared* s );
sigAct action;
sigset_t signalset;
static void catchSig( int sig ); // interacts with the shared resource
// it starts up the threads
};
记下指向自身的新static
指针。这样做是为了让我可以访问变量sh
,这是我需要的共享资源。我使用的是:
void Child::sig_handler::catchSig(int sig) {
self->sh->setStartFlag(true); // this was were it used to complain
}
sig_handler
是在Child
构造函数(sigHand = new sig_handler(share)
)中创建的。我得到了下面说明的构建时错误。怎么了?如何解决这个问题?
"Child::sig_handler::self", referenced from:
Child::sig_handler::sig_handler(Shared*) in Child.o
Child::sig_handler::catchSig(int) in Child.o
ld: symbol(s) not found for architecture x86_64
基本上,遗憾的是,它不可能成为sig_handler
课程。