你还未够水准呢 发表于 2012-11-15 21:33

APUE 270页的一个疑惑

本帖最后由 你还未够水准呢 于 2012-11-15 21:34 编辑

#include "apue.h"
#define pr_mask printf

static void sig_int(int);

int main(void)
{
    sigset_t    newmask, oldmask, waitmask;

    pr_mask("program start: \n");

    if (signal(SIGINT, sig_int) == SIG_ERR)
      err_sys("signal(SIGINT) error");
    sigemptyset(&waitmask);
    sigaddset(&waitmask, SIGUSR1);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGINT);

    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
      err_sys("SIG_BLOCK error");
   
    pr_mask("in critical region: \n");

    if (sigsuspend(&waitmask) != -1)
      err_sys("sigsuspend error");

    pr_mask("after return from sigsuspend: \n");

    //if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
      //err_sys("SIG_SETMASK error");

    pr_mask("program exit: \n");

    exit(0);
}

static void sig_int(int signo)
{
    pr_mask("\nin sig_int: \n");
}上面的代码我注释了两行

sigsuspend返回后进程中的屏蔽字是newmask 那应该屏蔽了 SIGINT啊
我在按下 Crtl+C 依然执行了sig_int(int signo)函数啊

不是阻塞了 SIGINT信号么

只为你飘的雪 发表于 2012-11-16 11:10

主要原因是sigsuspend函数的作用:它使本进程的信号屏蔽字设置为waitmask所指向的信号值。你这里是sigusr1,所以不能屏蔽sigint信号了。你试试用其他信号试试吧。希望对你有用,我也是在看unix环境高级编程,一起学习哟!

你还未够水准呢 发表于 2012-11-16 11:21

本帖最后由 你还未够水准呢 于 2012-11-16 11:22 编辑

但是sigsuspend返回后不是恢复了进程屏蔽字么

我这个注释了 貌似sigsuspend就没返回了。。。

我再添加个信号 让sigsuspend返回试一试

只为你飘的雪 发表于 2012-11-16 11:10 static/image/common/back.gif
主要原因是sigsuspend函数的作用:它使本进程的信号屏蔽字设置为waitmask所指向的信号值。你这里是sigusr1, ...

linux_c_py_php 发表于 2012-11-16 11:51

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#define pr_mask printf
#define err_sys printf

int n = 0;
static void sig_int(int);

int main(void)
{
      sigset_t newmask, oldmask, waitmask;

      pr_mask("program start: \n");

    //1, 锁信号(阻塞SIGINT, SIGUSR1)
      sigemptyset(&waitmask);
      sigaddset(&waitmask, SIGUSR1);
      sigemptyset(&newmask);
      sigaddset(&newmask, SIGINT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
                err_sys("SIG_BLOCK error");

    //2, 注册处理函数. (1与2最好保持顺序, 以免在注册后立即到来信号丢失事件)
    if (signal(SIGINT, sig_int) == SIG_ERR)
                err_sys("signal(SIGINT) error");

      pr_mask("in critical region: \n");

    //3, 这里用错了, 用oldmask释放掉SIGINT,SIGUSR1的阻塞
    //给你看看真正的安全信号编程是怎么回事
    while (!n) { //此处已被锁保护, 检查变量
      sigsuspend(&oldmask); //条件不满足, 原子释放锁+挂起
    }

    //条件满足, 安全打印n
      pr_mask("after return from sigsuspend: %d\n", n);

    //4, 释放掉信号锁
    sigprocmask(SIG_SETMASK, &oldmask, NULL);

    //5, 此后操作n是不安全的.
      pr_mask("program exit: \n");

      exit(0);
}

static void sig_int(int signo)
{
    n = 1;
      pr_mask("\nin sig_int: \n");
}楼主好好吸收一下吧, 对你掌握后面的条件变量也有好处.

只为你飘的雪 发表于 2012-11-16 11:55

你注释后,主进程在你还没有键入信号的时候,就已经退出了。你应该用pause,等待输入信号。回复 3# 你还未够水准呢


   

只为你飘的雪 发表于 2012-11-16 12:03

你这个就有些像互斥锁、条件变量的,安全机制是高了好多的啊。回复 4# linux_c_py_php


   
页: [1]
查看完整版本: APUE 270页的一个疑惑