这个问题早在使用signal时就碰到过,好不容易找到signal使用static型类成员函数的方法,但是发现不能传递参数,终究还是不行,直到在《APUE》上看到pthread和signal这一节,找到sigwait这个工具,这个问题总算是得到解决。 **************************************************************************************************** 为了叙述的方便,使用一个实际的例子,目的很简单,期望能够完成类似signal(signo,类成员函数)这样的功能。 先说说为什么不能直接使用signal(signo , 类成员函数)这种形式,signal函数的原型如下: -------------------------------------------------------------- void (*signal(int signo,void (*func)(int)))(int); signo:表示需要处理的信号; func:是一个指向void funciont(int)类型的函数指针; 返回值:返回值是一个指向void function(int)类型的函数指针。 这是因为普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而实现程序函数可以访问类型成员。这也可以理解为什么C++类的多个实例可以共享成员函数却有不同的数据成员。由于this指针的作用,使得将一个类型的成员函数作为signal函数参数时就会因为隐含的this指针使得函数参数不匹配,从而导致signal函数失败。 (摘自:http://www.cnblogs.com/this-543273659/archive/2011/08/17/2143576.html) 上面的这个问题和类成员函数作为线程函数一样,下面这篇文章中说过解决的办法: http://blog.sina.com.cn/s/blog_ac9fdc0b0101mhxp.html 使用static虽然貌似可以,但pthread_create和signal有一个本质的区别。pthread_create可以传入参数,这样可以将this作为参数传递给线程函数,然后利用this来调用类型成员函数,但是singal的信号处 理函数只能是void function(int)形式,不能想办法将this传递进去。这是最主要的问题,而且在我看来貌似是无解,即使是使用signal 的高端搞法sigaction也不行。因为signal是由内核发出的,它真心不知道这么多东西(这句话瞎说的),所以这条路走不通。下面是一种曲线救国的方法,可以实现完全相同的功能。 流程如下: (1)使用sigaddset创建信号屏蔽集(需要处理的信号); (2)使用pthread_sigmask阻止信号发送给当前进程中所有线程; (3)创建处理信号的线程函数signalThreadFunction(static类型)。需要传递this参数,可以参考:http://blog.sina.com.cn/s/blog_ac9fdc0b0101mhxp.html (4)在线程函数中还原this,利用this调用实际处理信号的类成员函数this->signalFunction; (5)在处理信号的类成员函数signalFunction中使用sigwait来等待信号的发生,然后可以随意的处理了。 ----------------------------------------------------------------------------------- codes speak much more than words: 14 //=========================================== 15 16 void error(const char *message) 17 { 18perror(message); 19exit(-1); 20 } 21 22 //========================================== 23 //main function wait the Ctrl+ to quit 24 //wait for Ctrl+c to show interrupt 25 class SignalKiller 26 { 27 public: 28SignalKiller() 29:quitFlag_(0) 30{ 31if(pthread_mutex_init(&lock_,NULL) != 0) 32error("error in pthread_mutex_init"); 33if(pthread_cond_init(&wait_,101)">34error("error in pthread_cond_int"); 35} 36~SignalKiller() 3738if(pthread_mutex_destroy(&lock_) != 0) 3940if(pthread_cond_destroy(&wait_) != 0) 414243 44void run(); 45 private: 46static void *signalThreadFunction(void *arg); 47void signalFunction(); 48 private: 49int quitFlag_; 50sigset_t mask_; 51pthread_mutex_t lock_; 52pthread_cond_t wait_; 53 }; 54 55 //=========================================== 56 voidSignalKiller::run() 57 { 58sigset_t oldMask; 59pthread_t thread; 60 61sigemptyset(&mask_); 62sigaddset(&mask_,SIGINT); 63sigaddset(&mask_,SIGQUIT); 64 65if(pthread_sigmask(SIG_BLOCK,&mask_,&oldMask) != 0) 66error("error in pthread_sigmask"); 67 68if(pthread_create(&thread,NULL,signalThreadFunction,(void*)this) != 0) 69error("error in pthread_create"); 70 71///wait for quitFlag to be 1 72pthread_mutex_lock(&lock_); 73while(quitFlag_ == 0) 74pthread_cond_wait(&wait_,&lock_); 75pthread_mutex_unlock(&lock_); 76 77//reset the signal mask to be old mask 78if(sigprocmask(SIG_SETMASK,&oldMask,NULL) < 0) 79error("error in sigprocmask"); 80 } 81 82 //=============================================== 83 void *SignalKiller::signalThreadFunction(void *arg) 84 { 85SignalKiller *thisOne = (SignalKiller*)arg; 86//using the member function to process signal 87thisOne->signalFunction(); 88return NULL; 89} 90 91 //=============================================== 92 void SignalKiller::signalFunction() 93 { 94int signo; 95 96while(1) 9798if(sigwait(&mask_,&signo) != 0) 99error("error in sigwait"); 100 101switch(signo) 102103case SIGINT: 104printf("ninterruptn"); 105break; 106case SIGQUIT: 107108printf("nquitn"); 109110quitFlag_ = 1; 111112pthread_cond_signal(&wait_); 113exit(0); 114115default: 116printf("unexcepted signal %dn",signo); 117exit(1); 118119120 } 121 122 //================================================ 123 int main() 124 { 125SignalKiller chenHuan; 126chenHuan.run(); 127 128return 0; 129 } 结果突出一个洋气: [chenhuan:~/Dropbox/programming_unix/lesson12]$./chen ^C interrupt ^ quit [chenhuan:~/Dropbox/programming_unix/lesson12]$ 每次说举个简单的例子,写着写着就上百行了。想当年考计算机二级,50行代码就顶天了,上机考试碰到链表几乎就是一个字“死”,哈哈,那时真是挺欢乐的~~~~
可找到的出处为【http://blog.csdn.net/wangkaiming123456/article/details/46775651】 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|