linux下信号编程简介——不可靠的信号

原创 2004年06月25日 13:53:00

两年前的文章,贴过来充充门面。

————————————————————

linux下信号编程简介——不可靠的信号

( 作者:mikespook | 发布日期:2002-12-8 | 浏览次数:135 )

关键字:linux,信号,signal()
前言:
    本文章只是为了给广大和我一样的菜鸟一个指引。如果你是高手,或对编程毫无兴趣。建议请不要在此浪费时间。

  信号是什么?其实这是一个很有意思的东西。比如说汽车行驶在路上相互鸣笛这就是信号;同样遇到红灯必须停下来这也是信号。对应到操作系统中,假设进程就是汽车,那么进程之间可以发送信号;同样如果假设操作系统是公路系统,那么操作系统也可以向进程发送信号。
    在linux中信号分为不可靠(或叫不安全)的信号与可靠的信号。后面我会解释为什么这么说。
    首先,简单介绍一下linux系统中的通用信号:
    SIGHUP   终端线以挂起。这是指当丢失载波信号时调制解调器线的挂起操作。然而,当它用logout函数关闭时,也将适用于任一终端设备。
    SIGINT   终端线已经收到中断字符。
    SIGQUIT  终端线已经收到退出字符。
    SIGUSR1  用户定义信号1。
    SIGUSR2  用户定义信号2。
    SIGTERM  正被终止的进程。
    SIGCHLD  一个子进程已经终止。
    SIGPIPE  半关闭管道发生写操作。
    SIGALRM  Alarm函数记时器到时。
    再来看看要用的函数signal()。signal()函数的定义在头文件 signal.h 中,它的函数原形是 sig_t signal(int sig, sig_t func); 第一个参数是想要注册的信号,第二个参数是指向信号处理函数的指针,或默认操作。系统提供了两种默认操作:SIG_DEL 和 SIG_IGN,分别是默认信号操作和忽略信号。

    好了说了一大堆枯燥无味的东西,有些晕了。单刀直入,看一个程序把。还记得上次那个多进程的程序么?我对其进行了一些修改。使得当子进程运行结束后不必等父进程顺序运行到 wait() 函数,而是直接转入信号处理函数。唉,复杂说不清楚。自己看吧!

/*--------------------------signal_fork.c------------------------------*/
/* mikespook */
/* exercise function signal() */
/* 2002.7.18 */

#include
#include
#include
#include
#define FAC_N 65535

/* 子进程调用的函数,这里我为了模拟一个很大的后台操作用了一个循环。 */
void big_loop(int n);
/* 父进程调用的函数,其实不放到函数里也可以,不过为了程序的结构更好看还是放到函数里的好 */
void input_information();
/* 信号处理函数,当父进程收到SIGCHLD信号的时候就会转入该函数进行操作 */
void handler();

int main()
{
  /* 进程号 */
  pid_t pid;
  /* 想用信号?那先对信号处理函数进行注册,对应起来 */
  signal(SIGCHLD, handler);
  /* 程序在这里“分叉”,新的进程创建了 */
  pid = fork();
  /* 通过fork()的返回值来判断是父进程还是子进程 */
  switch(pid){
    /* 返回 -1,很不幸,创建进程失败了。可能是没有足够的内存空间,也可能已经开起了太多的进程。 */
    case -1:
      perror("fork/n");
      break;
    /* 返回 0,现在是在子进程里运行,那就调用子进程的操作函数。 */
    case 0:
      /* 一个运行65535次的循环,如果你的机子太快,不能看清楚两个进程同时运行的效果,那就再加大循环次数。或用sleep()函数 */
      big_loop(FAC_N);
      /* 取得子进程的PID,你可以看清楚子进程和父进程的PID是不同的(子进程的PID比父进程的要大,因为是在父进程运行后才创建的)。*/
      printf("PID:%d/n", getpid());
      /* 子进程执行完了,发送信号 SIGCHLD。由于前面对这个信号进行了注册,这时就会转入信号处理操作。 */
      break;
    /* 哈哈,返回的即不是错误,又不是子进程,那就是父进程喽。*/
    default:
      /* 这里让用户输入了4个数 */
      input_information();
      /* 取得子进程的PID。*/
      printf("PID:%d/n", getpid());
      break;
  }
  exit(0);  
}

/*big_loop: 简单,一看就明白,不解释了。*/
void big_loop(int n)
{
  int i;
  for(i = 0; i < n; i++){
    switch(i % 4){
      case 0:
        putchar('-');
        break;
      case 1:
        putchar('/');
        break;
      case 2:
        putchar('|');
        break;
      case 3:
        putchar('//');
        break;
    }
    putchar('/b');
  }
}

/*input_information: 简单,一看就明白,也不解释了。*/
void input_information()
{
  int n_table[4], i;

  for(i = 0; i < 4; i++){
    printf("Number %d:/t", i);
    scanf("%d", &n_table[i]);
  }

   printf("Number1/tNumber2/tNumber3/tNumber4/n");
   printf("%d/t%d/t%d/t%d/n", n_table[0], n_table[1], n_table[2], n_table[3]);
}

/* 信号处理函数,当子进程结束的时候会向父进程发送 SIGCHLD 信号,这时程序会转入这个函数里进行处理 */
void handler()
{
  /* 父进程确认,子进程退出 */
  wait();
}
/*--------------------------signal_fork.c------------------------------*/

    看到了吧,信号的使用还是很简单的。但是这是不可靠的信号使用方法。为什么?道理很简单,当你程序运行的时候收到一个需要处理的信号,你的程序就会转入信号处理函数,对信号进行处理,处理完后再继续执行后续程序。在这个过程中如果正好是执行 malloc() 这样的函数时收到了信号,那么当信号处理完毕后因为 malloc() 不是一个可重入的函数,程序不会继续执行 malloc() ,这样空间也许不会分配,而造成错误。所以我们还需要可靠的信号处理方式,也就是说当执行某些不可被中断的操作的时候屏蔽掉信号处理。直到这些关键操作完成,再对信号进行处理。以后我会给大家详细的解释可靠信号的操作。
由于我是菜鸟,或许有什么不对的地方。也可能一些细节我没有考虑到。如果你知道的话希望不惜指教。小弟感激不尽!!

linux下信号编程简介——不可靠的信号

linux下信号编程简介——不可靠的信号( 作者:mikespook | 发布日期:2002-12-8 | 浏览次数:135 )关键字:linux,信号,signal() 前言:     本文章只是为...
  • ljx0305
  • ljx0305
  • 2008年05月15日 22:13
  • 1409

Linux可靠/不可靠信号编程实践

综合案例     1) 创建子进程与父进程;     2) 注册SIGINT非实时信号与SIGRTMIN实时信号,并将这两种信号添加到进程屏蔽信号组中;     3) 注册用...
  • u012377333
  • u012377333
  • 2014年11月24日 10:15
  • 999

Linux网络编程:信号

一、为了理解信号,先从我们最熟悉的场景说起: 1. 用户输入命令,在Shell下启动一个前台进程。 2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断。 3. 如果CPU当前正在执行这个进...
  • u012814360
  • u012814360
  • 2014年09月14日 16:47
  • 649

Linux C编程之信号介绍

这几天写了CSAPP的实验,用C语言实现一个简单的SHELL,为了做这个实验,把APUE信号相关的内容看了一遍,这里跟大家分享一下。 Unix信号使用总结: 信号的原理: 信号是一种进程...
  • rommel1
  • rommel1
  • 2012年03月21日 19:43
  • 2490

linux signal信号处理过程与机制--完全实例讲解

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。  信号机制是进程之间相互传递消息的一种方法...
  • lee244868149
  • lee244868149
  • 2014年08月20日 17:08
  • 2616

信号可靠、不可靠的原因

原文地址:http://blogold.chinaunix.net/u1/48788/showart.php?id=2270724早期的信号,也就是前32位的信号,在处理信号时,不具备阻塞该信号的能力...
  • zhenhuibox
  • zhenhuibox
  • 2011年07月15日 15:02
  • 521

linux信号基本概念及如何产生信号

阅前须知本文的主要内容有:1.信号的基本概念(包括进程对信号的3种处理方式)2.特殊信号举例:写代码证明信号存在,并实现信号的简单捕捉3.如何产生一个信号(代码举例:mykill的实现)其中拓展知识有...
  • summy_J
  • summy_J
  • 2017年06月14日 09:34
  • 856

Linux_信号与信号量

信号: 信号机制是类UNIX系统中的一种重要的进程间通信手段之一。我们经常使用信号来向一个进程发送一个简短的消息。例如:假设我们启动一个进程通过socket读取远程主机发送过来的网络数据包,此时由于网...
  • sty23122555
  • sty23122555
  • 2016年05月22日 09:52
  • 1588

Linux下,使用C/C++编写的一个简单的信号处理例程

// main.c file#include #include #include // linux header file#include #include #include //void MySig...
  • wenxy1
  • wenxy1
  • 2005年12月15日 16:57
  • 1726

Linux下信号--阻塞信号

这篇博客http://blog.csdn.net/l_xrui/article/details/72885978讲了信号的基本概念与产生方式。 了解以下三种概念: 信号递达(Delivery):实...
  • L_XRUI
  • L_XRUI
  • 2017年06月07日 00:00
  • 587
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux下信号编程简介——不可靠的信号
举报原因:
原因补充:

(最多只允许输入30个字)