http://bbs.chinaunix.net/thread-989499-1-1.html
今天做的能够实现进程间发送自己定义的信号了,并且可以带参数。
不过发现没多大用处,因为Linux上留了 SIGRTMIN(32)到SIGRTMAX(64)等三十二个可靠信号,可以给应用程序用,基本上已经够用了。
如果用Linux的信号的话,也可以带参数,就是用 sigqueue函数来发送信号,这个函数只可以给一个进程发送信号。
今天做的思路变了一下,就是调用我自己的类的成员函数发送信号之前,我会利用Linux上的共享内在技术(shmget/shmat/shmdt等函数),把要发送的自定义消息,以及所带的参数写到共享内存,然后接收信号的进程收到某个特定的信号之后,再去读共享内存,再把共享内存里面的参数信息交给用户自己定义的信号处理函数处理。
我在CSDN上看见有人问下面这样一个问题:
----------------------------------------------------------------------------------
标题:LINUX下的自定义信号如何实现(不使用系统的SIGUSR1和SIGUSR2)
内容:
(1)例如:
#define SIG_MY_MSG SIGUSR1+100
当我调用kill(0,SIG_MY_MSG)时,系统能够识别出SIG_MY_MSG信号。
----------------------------------------------------------------------------------
有人说要改Linux内核,将信号的最大值64修改大一些,我不会改内核,写出下面的代码,来实现进程内的的自定义信号发送(进程间的自定义信号发送还得加代码),大家看还有更好的方法吗?拍砖一下,我对自己写的代码没自信,从来没有人看过我写的程序。
大概的思路是这样的:
1、进程里面有一个自定义的单件信号处理类
2、信号处理类里面有一个向量表,来保存用户安装的自定义信号和相应的信号处理函数
3、发送信号时,调用自己的信号发送函数,自己定义的信号发送函数会保存用户发送的信号的值
- #include <iostream>
- #include <sys/types.h>
- #include <sys/params.h>
- #include <signal.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <vector>
- using namespace std;
- #define MYSIG_MSG SIGUSR1 + 2 // 自定义的信号,类似于windows平台的 #define WM_MYMESSAGE WM_USER + 2
- #define MYSIG_MSG SIGUSR1 + 3
- #define MYSIG_MSG SIGUSR1 + 4
- #define MYSIG_MSG SIGUSR1 + 5
- void Handler_MSG(unsigned long sig) // 自定义的信号处理函数,linux的信号处理函数的参数是int,我这里用unsigned long
- {
- write( 2, "Handler_MSG/n", 12 );
- }
- void Handler_MSG2(unsigned long sig)
- {
- write( 2, "Handler_MSG2/n", 13 );
- }
- void Handler_MSG3(unsigned long sig)
- {
- write( 2, "Handler_MSG3/n", 13 );
- }
- void Handler_MSG4(unsigned long sig)
- {
- write( 2, "Handler_MSG4/n", 13 );
- }
- class CSignalHandler // 单件信号处理类,安装和发送自定义的信号都调用此类的成员函数
- {
- protected:
- typedef void (*SIG_HANDLER_PF)(unsigned long sig); // 定义一个指向信号处理函数的指针
- struct tagSigaction // 定义一个结构体,结构体的一个成员是自定义的信号,另一个成员是个处理自定义信号的函数的指针
- {
- unsigned long m_ulSigNumber;
- void (*m_Handler)(unsigned long sig);
- };
- typedef vector<tagSigaction> SIGACTION_VECTOR; // 自定义信号的结构体数组
- typedef SIGACTION_VECTOR::iterator SIGACTION_VECTOR_IT;// 迭代器类型,用来访问vector
- SIGACTION_VECTOR m_SigactionVector; //把自定义的信号及信号处理函数,用vector保存起来
- unsigned long m_ulCurrentSigNumber; // 当前接收到的信号
- protected: // 构造函数定义成保护的,不让用户自己生成信号处理类对象,
- CSignalHandler()
- {
- ActionDefaultSigHandler();
- }
- ~CSignalHandler()
- {
- }
- public:
- static CSignalHandler* GetSignalHandler() // 获取信号处理类的全局访问点
- {
- static CSignalHandler signalhandler;
- return &signalhandler;
- }
- protected:
- // 当用户发送一个自定义的信号的时候,该函数就会被调用,然后根据用户发送的信号,调用用户设置的函数进行处理
- static void CustomSigHandler(int sig)
- {
- SIGACTION_VECTOR& SigactionVector = CSignalHandler::GetSignalHandler()->GetSigActionVector();
- SIGACTION_VECTOR_IT it;
- for ( it = SigactionVector.begin(); it != SigactionVector.end(); it++ )
- {
- if ( (*it).m_ulSigNumber == CSignalHandler::GetSignalHandler()->GetCurrentSigNumber() )
- {
- (*it).m_Handler( CSignalHandler::GetSignalHandler()->GetCurrentSigNumber() );
- }
- }
- }
- void ActionDefaultSigHandler() // 安装默认的SIGUSR1信号处理函数
- {
- struct sigaction act;
- act.sa_handler = CSignalHandler::CustomSigHandler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- assert( sigaction(SIGUSR1, &act, NULL) >= 0 );
- }
- unsigned long GetCurrentSigNumber() const // 获取当前发送的信号
- {
- return m_ulCurrentSigNumber;
- }
- void SetCurrentSigNumber(unsigned long ulCurrentSigNumber) // 当用户发送一个信号时,先设置信号值
- {
- m_ulCurrentSigNumber = ulCurrentSigNumber;
- }
- SIGACTION_VECTOR& GetSigActionVector() // 获取用户安装的信号vector的引用
- {
- return m_SigactionVector;
- }
- int Raise(unsigned long ulSig) // 发送自定义的信号
- {
- m_ulCurrentSigNumber = ulSig;
- return raise(SIGUSR1);
- }
- void Sigaction(unsigned long sig, SIG_HANDLER_PF pf) // 安装自定义的信号
- {
- struct tagSigaction sigact;
- sigact.m_ulSigNumber = sig;
- sigact.m_Handler = pf;
- m_SigactionVector.push_back(SIGACTION_VECTOR::value_type(sigact));
- }
- };
- int main(int argc, char* argv[])
- {
- CSignalHandler::GetSignalHandler()->Sigaction( MYSIG_MSG, Handler_MSG); // 安装自定义的信号
- CSignalHandler::GetSignalHandler()->Sigaction( MYSIG_MSG2, Handler_MSG2);
- CSignalHandler::GetSignalHandler()->Sigaction( MYSIG_MSG3, Handler_MSG3);
- CSignalHandler::GetSignalHandler()->Sigaction( MYSIG_MSG4, Handler_MSG4);
- CSignalHandler::GetSignalHandler()->Raise(MYSIG_MSG); // 发送自定义的信号
- CSignalHandler::GetSignalHandler()->Raise(MYSIG_MSG2);
- CSignalHandler::GetSignalHandler()->Raise(MYSIG_MSG3);
- CSignalHandler::GetSignalHandler()->Raise(MYSIG_MSG4);
- while (1)
- {
- sleep(1);
- }
- return 0;
- }