拥有梦想是一种智力,实现梦想是一种能力

 

概述

若是一个多线程的进程,由于各个线程共享一个地址空间,可以直接通过变量的形式进行通信。而进程,由于各个进程独占一个地址空间,我们需要一种通信机制来完成进程间的数据交互。本章介绍的是信号机制,进程间的通信机制有以下几种:

  • 无名管道(pipe)
  • 有名管道 (fifo)
  • 信号(signal)
  •  
  • 共享内存(share memory)
  • 消息队列(message queue)
  • 信号灯集(semaphore set)
  •  
  • 套接字(socket)

 

之间有区分与各自的运用场景,其中套接字通常使用在网络服务,其他只能在本地场景下使用。笔者以后会逐一学习,本章介绍信号机制。

 

 

信号

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式 。linux内核通过信号通知用户进程,不同的信号类型代表不同的事件 。

 

对信号,进程有不同的响应方式

  •  缺省方式,默认操作
  •  忽略信号,对信号不做任何处理(除了两个不可忽略的信号 SIGKILL和SIGSTOP)
  •  捕捉信号,定义用户处理函数

 

查看所有信号类型

kill -l 

 

 

常见信号

信号名

含义

默认操作

      SIGHUP

该信号在用户终端关闭时产生,通常是发给和该

终端关联的会话内的所有进程

           终止

       SIGINT

该信号在用户键入INTR字符(Ctrl-C)时产生,内

核发送此信号送到当前终端的所有前台进程

           终止

     SIGQUIT

该信号和SIGINT类似,但由QUIT字符(通常是

Ctrl-\)来产生

           终止

       SIGILL

该信号在一个进程企图执行一条非法指令时产生

           终止

       SIGSEV

该信号在非法访问内存时产生,如野指针、缓

冲区溢出

           终止

      SIGPIPE

当进程往一个没有读端的管道中写入时产生,代

管道断裂

           终止

信号名

含义

默认操作

SIGKILL

该信号用来结束进程,并且不能被捕捉和忽略

终止

SIGSTOP

该信号用于暂停进程,并且不能被捕捉和忽略

暂停进程

SIGTSTP

该信号用于暂停进程,用户可键入SUSP字符(

通常是Ctrl-Z)发出这个信号

暂停进程

SIGCONT

该信号让进程进入运行态

继续运行

SIGALRM

该信号用于通知进程定时器时间已到

终止

SIGUSR1/2

该信号保留给用户程序使用

终止

 

信号命令 kill\killall

kill并不是要‘杀死’进程,虽然kill大部分的信号是和结束进程相关的,但它确确实实是向进程发送指定的信号。

 

kill [-signal] pid

  • 默认发送SIGTERM
  •  -sig 可指定信号
  • pid  指定发送对象

通常要杀死一个指定的进程

ps aux|grep abc
kill -9 `abc的PID`

 

killall [-u  user | prog]

  • prog  指定进程名
  • user  指定用户名

killall杀死同名进程

killall -9 bash

这样,bash以及bash相关联的服务进程都会被杀掉。

 

 

信号相关函数操作

 

kill()\raise()信号发送

 #include  <unistd.h>
 #include <signal.h>
 int  kill(pid_t pid,  int sig);
 int  raise(int sig);

  •  成功时返回0,失败时返回EOF
  •  pid 接收进程的进程号;0代表同组进程; -1代表所有进程
  •  sig 信号类型
     

与kill()不同的是,raise()只允许进程向自身发送信号。

 

alarm()定时发送信号

int  alarm(unsigned int seconds);

  •  成功时返回上个定时器的剩余时间,失败时返回EOF
  •  seconds 定时器的时间
  •  一个进程中只能设定一个定时器,时间到时产生SIGALRM

ps:alarm经常用于实现超时检测     

 

pause()进程阻塞

int pause(void);

  •  进程一直阻塞,直到被信号中断
  •  被信号中断后返回-1,errno为EINTR

 

signal()设置信号的响应方式

 #include  <unistd.h>
 #include <signal.h>
 void (*signal(int signo, void (*handler)(int)))(int);

  •  成功时返回原先的信号处理函数,失败时返回SIG_ERR
  •  signo 要设置的信号类型
  •  handler 指定的信号处理函数: SIG_DFL代表缺省方式; SIG_IGN 代表忽略信号;  

 

 

示例1

signal()设置信号的响应方式

void handler (int signo) {
     if (signo == SIGINT) {
        printf(“I have got SIGINT!\n”); }
     if (signo == SIGQUIT) {
        printf(“I have got SIGQUIT\n”); }
}

int  main() {
     signal(SIGINT, handler);
     signal(SIGQUIT, handler);
     while ( 1 ) pause();
     return 0;
}

 

示例2

alarm()定时结束进程

#include <stdio.h>  
#include <stdlib.h>
#include <unistd.h>
int main() {
   alarm(3);
   pause();
   printf(“I have been waken up!\n”);
   return 0;
}

$ ./a.out 
Alarm clock