sigsetjmp siglongjmp使用时要注意内存泄露
来源:互联网 发布:此windows副本不是正版 编辑:程序博客网 时间:2024/05/17 02:06
如果你在sigsetjmp条件内构造了一个对象,那么很容易造成内存泄露,程序的
突然跳转,导致析构函数还没有执行.以下是测试代码
#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <setjmp.h>#include <signal.h>#include <time.h>#include <assert.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <sys/time.h>#include <arpa/inet.h>#include <pthread.h>class A{public:A(){i=0;printf("constructor\n");}~A(){printf("unconstructor\n");}int i;};pthread_t tid_result_manager;jmp_buf jb_result_manager;void sigexit_main(int){printf("主线程接收到了退出信号。\n" );pthread_kill( tid_result_manager,SIGUSR1 );return;}void sigalrm(int s) { printf("sigalrm signal=%d\n",s); siglongjmp( jb_result_manager, 1 ); //此处返回1 ,继续执行}void sigexit(int s) {printf("sigexit signal=%d\n",s);pthread_t tid = pthread_self();if ( tid == tid_result_manager ) siglongjmp( jb_result_manager, -1 ); //返回-1assert(0);}int icout=0;void *result_manager( void * ){sigset_t set; int alarm_time = 2;int ret=0;printf("线程启动。\n" ); signal( SIGUSR1, sigexit ); signal( SIGALRM, sigalrm );sigemptyset( &set );sigaddset( &set, SIGUSR1 ); sigaddset( &set, SIGALRM ); pthread_sigmask( SIG_UNBLOCK, &set, NULL ); //不阻止SIGUSR1信号 if ( ( ret = sigsetjmp( jb_result_manager, 1 ) ) != -1 ) { if ( ret ) {printf("ret=%d,alarm_time=%d\n",ret,alarm_time);pthread_sigmask( SIG_BLOCK, &set, NULL );icout++;if(icout<5){alarm( alarm_time ); }A a;a.i++;printf("cccc a.i=%d\n",a.i);sleep(5);alarm(0); //取消定时器printf("线程内 ,取消 定时器之后 \n");pthread_sigmask( SIG_UNBLOCK, &set, NULL ); // while ( 1 ) pause(); //让程序等待信号}printf("waiting signal。\n" );while ( 1 ) pause(); //让程序等待信号}printf("线程退出。\n" );return NULL;}int main( int argc, char *argv[] ){ printf("pid=%d",getpid());sigset_t set;sigfillset( &set );sigprocmask( SIG_BLOCK, &set, NULL ); pthread_create( &tid_result_manager, NULL, result_manager, NULL ); signal( SIGINT, sigexit_main );signal( SIGTERM, sigexit_main );signal( SIGQUIT, sigexit_main );sigemptyset( &set );sigaddset( &set, SIGINT );sigaddset( &set, SIGTERM );sigaddset( &set, SIGQUIT );pthread_sigmask( SIG_UNBLOCK, &set, NULL );sleep(5); pthread_kill( tid_result_manager, SIGALRM );printf("SIGALRM sigal sended\n");pthread_join( tid_result_manager, NULL );printf("program退出。\n" );return 0;}
打印结果为
pid=5487线程启动。
waiting signal。
SIGALRM sigal sended
sigalrm signal=14
ret=1,alarm_time=2
constructor
cccc a.i=1
线程内 ,取消 定时器之后
sigalrm signal=14
ret=1,alarm_time=2
constructor
cccc a.i=1
线程内 ,取消 定时器之后
sigalrm signal=14
ret=1,alarm_time=2
constructor
cccc a.i=1
线程内 ,取消 定时器之后
sigalrm signal=14
ret=1,alarm_time=2
constructor
cccc a.i=1
线程内 ,取消 定时器之后
sigalrm signal=14
ret=1,alarm_time=2
constructor
cccc a.i=1
线程内 ,取消 定时器之后
unconstructor
waiting signal。
主线程接收到了退出信号。
sigexit signal=10
线程退出。
program退出。
可以很明显的看到析构函数就执行了最后一次,所以使用时一定要小心.尽可能少使用sigsetjmp siglongjmp函数,有个问题,为什么线程内 ,取消 定时器之后能被打印出来?
0 0
- sigsetjmp siglongjmp使用时要注意内存泄露
- sigsetjmp,siglongjmp的使用
- sigsetjmp,siglongjmp的使用
- sigsetjmp,siglongjmp的使用
- sigsetjmp,siglongjmp的使用
- sigsetjmp & siglongjmp
- sigsetjmp, siglongjmp
- siglongjmp、sigsetjmp
- alarm,sigsetjmp,siglongjmp
- alarm,sigsetjmp,siglongjmp 注意事项
- sigsetjmp, siglongjmp函数说明
- siglongjmp 和 sigsetjmp 用法
- 关于sigsetjmp和siglongjmp
- sigsetjmp和siglongjmp详解
- Sigsetjmp 和 Siglongjmp
- 关于sigsetjmp,siglongjmp注意点 (UDP超时重传应用)
- csapp读书笔记-使用setjmp/sigsetjmp和longjmp/siglongjmp进行非本地跳转
- Linux Signal (8): sigsetjmp和siglongjmp
- jbpm 总结
- Myeclipse10下搭建SSH框架(图解)St…
- 怎样将jpg转成pdf格式
- hibenate集合映射
- Hibernate反向工程使用心得
- sigsetjmp siglongjmp使用时要注意内存泄露
- <tx:method/> 有关的设置
- form表单提交后页面的跳转
- struts2的文件下载
- Oracle的查询
- Oracle 11g 下载|Oracle…
- Oracle的安装
- 自定义MFC CEdit控件的外观
- BeanUtils.copyProperties() 用法