C + UNIX,siglongjmp和sigsetjmp

 我只是狼却有幅羊的心肠_152 发布于 2023-02-09 17:54

我有一个(古老的)教科书中的程序,旨在说明UNIX上POSIX信号的使用。该程序运行一个计算循环,以从固定点开始计算理想数。

时间警报信号用于定期打印状态。

中断信号用于按需状态。

退出信号用于重置测试间隔(或终止)。


void perfect(int);

sigjmp_buf jmpenv; /* environment saved by setjmp*/

int n; /* global variable indicating current test point */

int main() {

    int begin; /* starting point for next search*/
        /* interrupt routines*/
    void status();
    void query();

    sigset_t mask;
    struct sigaction action;


    if (sigsetjmp(jmpenv,0)) {
        printf("Enter search starting point (0 to terminate): ");
        scanf("%d",&begin);
        if (begin==0) exit(0);
        sigprocmask(SIG_UNBLOCK, &mask, NULL);
        }
    else begin=2;

    /* Status Routine will handle timer and INTR */

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGALRM);
    sigaddset(&mask, SIGQUIT);
    action.sa_flags=0;
    action.sa_mask=mask;

    action.sa_handler=status;
    sigaction(SIGINT,&action,NULL);
    sigaction(SIGALRM,&action,NULL);

    action.sa_handler=query;
    sigaction(SIGQUIT,&action,NULL);

    /* start alarm clock */
    alarm(20);
    perfect(begin);
}

void perfect(start) 
    int start;
{
    int i,sum;

    n=start;

while (1) {
    sum=1;
    for (i=2;i

我的问题是:

    为什么调用void status(); 和void query(); 首先是主要的?

    在if语句检查begin == 0并决定退出之后,它遵循名为“ sigprocmask(SIG_UNBLOCK,&mask,NULL);”的行。为什么我退出后必须将其解锁?

Jonathan Lef.. 5

    这两行声明函数status()query()返回void。他们没有指定要接受的参数。在现代C语言中,在另一个函数中声明函数就是“厌恶”(anathema)(而在没有完整原型的情况下声明它们也是“厌恶”,但这似乎是另一天的讨论,因为它不是您的代码)。函数应在其他函数之外声明,并且如果它们在其他文件中定义或使用,则应在标头中声明。如果它们是在当前文件中定义的,而未在任何其他文件中使用,则应将它们声明为static函数。

    该变量begin非常规地初始化。在第一次通过代码时将其设置为2;从返回非零值后sigsetjmp(),由用户输入设置。它也很可能被这些setjmp()东西淹没,因为它没有被标记volatile。规则是深奥的。

    但是,其目的是如果begin为零,则程序退出。否则,它将继续。在sigprocmask()旨在解除蒙面的任何信号。我不清楚这是否必要。从信号处理程序返回时,即使您通过退出,被阻止的信号也应被解除阻止(我认为)siglongjmp()

请注意,printf()在信号处理程序中调用会调用未定义的行为。可能会好的,但是不能保证。在POSIX标准中或在SO上的其他问题中都有一个可以调用的函数列表(我知道我之前已经给出了该列表)。


请仔细阅读手册中的功能:

sigsetjmp()

siglongjmp()

setjmp()

longjmp()

多德是正确的,当他评论说sigsetjmp()为0的第二个参数不保存当前的信号掩码。请注意,的值mask在一个局部变量中,该变量在之后被修改setjmp()且未标记volatile,因此在setjmp()返回非零值时其值是不确定的(请参见setjmp()手册页中的警告)。

手册页的基本原理部分sigsetjmp()非常有趣,并提到了4.2 BSD(于1982年发布)中出现的类似功能,因此我对它们在70年代不存在的评论仍然有效(K&R 1st Edition和7th Edition UNIX™于1978年发布)和1979)。的sig*名字是,AFAICT,由POSIX发明(包括在BSD系统_setjmp()_longjmp()代替)。

1 个回答
    1. 这两行声明函数status()query()返回void。他们没有指定要接受的参数。在现代C语言中,在另一个函数中声明函数就是“厌恶”(anathema)(而在没有完整原型的情况下声明它们也是“厌恶”,但这似乎是另一天的讨论,因为它不是您的代码)。函数应在其他函数之外声明,并且如果它们在其他文件中定义或使用,则应在标头中声明。如果它们是在当前文件中定义的,而未在任何其他文件中使用,则应将它们声明为static函数。

      该变量begin非常规地初始化。在第一次通过代码时将其设置为2;从返回非零值后sigsetjmp(),由用户输入设置。它也很可能被这些setjmp()东西淹没,因为它没有被标记volatile。规则是深奥的。

      但是,其目的是如果begin为零,则程序退出。否则,它将继续。在sigprocmask()旨在解除蒙面的任何信号。我不清楚这是否必要。从信号处理程序返回时,即使您通过退出,被阻止的信号也应被解除阻止(我认为)siglongjmp()

    请注意,printf()在信号处理程序中调用会调用未定义的行为。可能会好的,但是不能保证。在POSIX标准中或在SO上的其他问题中都有一个可以调用的函数列表(我知道我之前已经给出了该列表)。


    请仔细阅读手册中的功能:

    sigsetjmp()

    siglongjmp()

    setjmp()

    longjmp()

    多德是正确的,当他评论说sigsetjmp()为0的第二个参数不保存当前的信号掩码。请注意,的值mask在一个局部变量中,该变量在之后被修改setjmp()且未标记volatile,因此在setjmp()返回非零值时其值是不确定的(请参见setjmp()手册页中的警告)。

    手册页的基本原理部分sigsetjmp()非常有趣,并提到了4.2 BSD(于1982年发布)中出现的类似功能,因此我对它们在70年代不存在的评论仍然有效(K&R 1st Edition和7th Edition UNIX™于1978年发布)和1979)。的sig*名字是,AFAICT,由POSIX发明(包括在BSD系统_setjmp()_longjmp()代替)。

    2023-02-09 17:55 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有