我可以撤消或删除 atexit 命令吗?

发布于 2024-08-22 15:11:01 字数 1702 浏览 7 评论 0原文

如果我将 atexit( fn ); 放在退出堆栈上,它将在程序退出时执行:从 main() 返回或通过 exit()< /代码>。

我可以将其从堆栈中删除吗?

你问我为什么要这样做?

我正在使用 atexitsetjmplongjmp 尝试一种简单的 try-catch 机制。如果我可以 undo-atexit(fn); - 即使它只适用于最后注册的函数,那就完美了。

编辑:

按照 monoceres 的建议制作我自己的堆栈...

该堆栈目前仅适用于一个异常捕获器。

void (*_catchFn[10])()  = {0,0,0,0,0,0,0,0,0,0};

void _catch(){
  if ( _catchFn[0] != 0 ){
    (_catchFn[0])();
  }
}

void _addCatch( void (*fn)() ){
  _catchFn[0]=fn;
}

void _remCatch( void (*fn)() ){
  _catchFn[0]=0;
}

void test(){
  jmp_buf env;

  void catch(){                  // we get here after an exit with a registered catch
    longjmp(env,1);              // return to the line marked except...
                               //   that first will get the value 1
  }
  int first = setjmp( env);      // ** return here **
  fprintf( stderr , "test: After setjmp. first=%d\n" , first );
  if( first == 0 ){              // try this code
    _addCatch(catch);            // register the catch function to 'catch' the exit
    fprintf( stderr , "test: Before CHECK\n" );
    // CHECK something and something bad happens and it exits
    exit(1);                     // like this
    fprintf( stderr , "test: After CHECK - THIS SHOULD NEVER BE SEEN AFTER AN EXCEPTION.\n" );
  }else{
    fprintf( stderr , "test: After longjmp return. first=%d\n" , first );
  }
  _remCatch( catch);
  fprintf( stderr , "test: IT WORKED!\n");
  exit(1);  // exit again to see if we are safe
}

int main(){
  atexit( _catch );              // register my global exception stack
  test();
}

If I place atexit( fn ); on the exit stack, it will get executed when the program exits: returns from main() or via exit().

Can I remove it from the stack?

Why do I want to do this, you ask?

I was experimenting with a simple try-catch mechanism using atexit, setjmp and longjmp. It would be just perfect if I could undo-atexit(fn); - even if it would only work for the last registered function.

Edit:

Following monoceres' suggestion to make my own stack...

The stack only works with one exception catcher for now.

void (*_catchFn[10])()  = {0,0,0,0,0,0,0,0,0,0};

void _catch(){
  if ( _catchFn[0] != 0 ){
    (_catchFn[0])();
  }
}

void _addCatch( void (*fn)() ){
  _catchFn[0]=fn;
}

void _remCatch( void (*fn)() ){
  _catchFn[0]=0;
}

void test(){
  jmp_buf env;

  void catch(){                  // we get here after an exit with a registered catch
    longjmp(env,1);              // return to the line marked except...
                               //   that first will get the value 1
  }
  int first = setjmp( env);      // ** return here **
  fprintf( stderr , "test: After setjmp. first=%d\n" , first );
  if( first == 0 ){              // try this code
    _addCatch(catch);            // register the catch function to 'catch' the exit
    fprintf( stderr , "test: Before CHECK\n" );
    // CHECK something and something bad happens and it exits
    exit(1);                     // like this
    fprintf( stderr , "test: After CHECK - THIS SHOULD NEVER BE SEEN AFTER AN EXCEPTION.\n" );
  }else{
    fprintf( stderr , "test: After longjmp return. first=%d\n" , first );
  }
  _remCatch( catch);
  fprintf( stderr , "test: IT WORKED!\n");
  exit(1);  // exit again to see if we are safe
}

int main(){
  atexit( _catch );              // register my global exception stack
  test();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱冒险 2024-08-29 15:11:01

为什么不构建您自己的堆栈并从单个 atexit() 函数调用?这样你就可以随心所欲地操纵堆栈。

Why not build your own stack that you call from a single atexit() function? That way you could manipulate the stack all you want.

未央 2024-08-29 15:11:01

不,您不能这样做,但您可以使用全局标志,因此如果设置了该标志,您的退出处理程序将不执行任何操作。

或者,您可以调用 _Exit() (C99) - 它将执行正常的退出过程(关闭所有打开的描述符,发送所有需要的信号和父/子),但不会调用退出处理程序。

No, you cannot do it, but you can use global flag so your exit handler will be doing nothing if the flag is set.

Alternatively you can call _Exit() (C99) - it will perform normal exit procedure (close all open descriptors, send all needed signals and parent/children) but will not call exit handler.

皇甫轩 2024-08-29 15:11:01

模块的 C 实现中有一个未记录的 atexit._clear 函数,可以执行此操作

https://github.com/python/cpython/blob/29c04dfa2718dd25ad8b381a1027045b312f9739/Modules/atexitmodule.c#L301

there is an undocumented atexit._clear func in the C implementation of the module that does this

https://github.com/python/cpython/blob/29c04dfa2718dd25ad8b381a1027045b312f9739/Modules/atexitmodule.c#L301

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文