信号量常见操作:
1.在进程中屏蔽指定信号量:每个进程都有自己的信号阻塞集合,把要进行屏蔽的信号量加入该集合,进程捕捉到该信号时将不进行处理,有两个信号不能忽略:SIGKILL及SIGSTOP
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:用于指定信号修改的方式,可能选择有三种
SIG_BLOCK //加入信号到进程屏蔽。
SIG_UNBLOCK //从进程屏蔽里将信号删除。
SIG_SETMASK //将set的值设定为新的进程屏蔽。
- sigset_t newmask,oldmask;
- sigemptyset(newmask);//初始话信号量集
- sigaddset(&newmask,SIGQUIT);//把SIGQUIT加入到信号量集
- //newmask置为当前进程的信号阻塞集合,并把标记保存在oldmask中
- sigprocmask(SIG_BLOCK,&newmask,&oldmask);
- //恢复被屏蔽的信号量
- sigprocmask(SIG_SETMASK,null,oldmask);
2.信号的发送
发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。
1、kill()
- #include <sys/types.h>
- #include <signal.h>
- int kill(pid_t pid,int signo)
2、raise()
- #include <signal.h>
- int raise(int signo)
向进程本身发送信号,参数为即将发送的信号值。调用成功返回 0;否则,返回 -1。
3.信号的安装,设置信号关联动作
1.signal
- #include <signal.h>
- void (*signal(int signum, void (*handler))(int)))(int);
如果该函数原型不容易理解的话,可以参考下面的分解方式来理解:
- typedef void (*sighandler_t)(int);
- sighandler_t signal(int signum, sighandler_t handler));
第一个参数指定信号的值,第二个参数指定针对前面信号值的处理,可以忽略该信号(参数设为SIG_IGN);可以采用系统默认方式处理信号(参数设为SIG_DFL);也可以自己实现处理方式(参数指定一个函数地址)。
如果signal()调用成功,返回最后一次为安装信号signum而调用signal()时的handler值;失败则返回SIG_ERR。
2、sigaction()
- #include <signal.h>
- int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
sigaction函数用于改变进程接收到特定信号后的行为。该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)。第二个参数是指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理;第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。如果把第二、第三个参数都设为NULL,那么该函数可用于检查信号的有效性。
第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等。
2.利用信号实现线程同步
a.在线程中设置等待的信号
- #ifndef __TCTHREAD__
- #define __TCTHREAD__
- #include <pthread.h>
- #include <signal.h>
- class TCThread
- {
- public:
- // @brief 构造函数
- TCThread();
- // @brief 析构函数
- ~TCThread();
- // @brief 启动线程
- bool Start();
- // @brief 线程停止
- void pause();
- // @brief 线程继续运行
- void continues();
- private:
- // @brief 屏蔽SIGUSR1信号
- void maskSIGUSR1();
- // @brief 信号量集合
- sigset_t g_waitSig;
-
- protected:
- //由子类实现具体任务逻辑
- virtual void Run() = 0;
- };
- #endif
- TCThread::TCThread()
- {
- maskSIGUSR1();
- // 定义SIGUSR1信号阻塞
- sigemptyset(&tcwaitSig);
- sigaddset(&tcwaitSig, SIGUSR1);
- }
- TCThread::~TCThread()
- {
- }
- void TCThread::maskSIGUSR1()
- {
- sigset_t sig;
- sigemptyset(&sig);//清空信号量集合
- sigaddset(&sig , SIGUSR1);//把SIGUSR1加入到信号量集合中
- pthread_sigmask(SITCBLOCK , &sig , NULL); //在线程中屏蔽sig信号量结合中的信号
- }
- bool TCThread::Start()
- {
- int nRet = pthread_create(&tcpid , NULL , threadFun , this);
- if(0 == nRet)
- {
- nRet = pthread_detach(g_pid);//线程退出时释放线程资源
- if(nRet == 0)
- {
- return true;
- }
- }
- else
- {
- return false;
- }
- return true;
- }
- void G_Thread::pause()
- {
- int sig;
- sigwait(&g_waitSig , &sig);//等待SIGUSR1信号
- }
- void G_Thread::continues()
- {
- pthread_kill(g_pid , SIGUSR1);//向线程发送SIGUSR1信号
- }
阅读(904) | 评论(0) | 转发(0) |