线程-》信号
信号,是unix和linux系统响应某些条件而产生的一个事件。接收到该信号的进程会相应地采取一些行动。
raise生成表示一个信号的产生
catch捕获表示接受到一个信号的产生;信号是由于某些错误条件而产生,内存段冲突,浮点处理器错误或者非法指令等。它们由shell和终端处理器生成
引起中断,可以作为进程见传递消息或修改行为的一种方式,明确地由一个进程发送给另一个进程。无论什么情况,它们的编程接口都是相同的,信号可以被
生成,捕获,响应,忽略。
signal.h====== sigabort *进程异常终止
sigalrm 超时警告
sigfpe *浮点运算错误
sighup 链接挂断
sigill *非法指令
sigint 终端中断
sigkill 终止进程(此信号不能被不或忽略)
sigpipe 向无读进程的管道写数据
sigquit 中断退出
sigsegv *无效内存段访问
sigterm 终止
siguser1 用户定义信号
siguser2 用户定义信号2
注意:*表示系统对信号的响应随具体实现而定
-----------》如果进程接受到这些信号中的一个,但事先没有安排不或他,进程将会立刻终止。通常系统会生产核心转储文件core,并将其放在当前
目录下。该文件是进程自爱内存中的印象,他对程序的调试很有帮助。 其他信号
sigchld 子进程已经停止或退出
sigcont 继续执行暂停进程
sigstop 停止执行(此信号不能被捕获或忽略)
sigstsp 终端挂起
sigttin 后台进程尝试读操作
sigttou 后台进程尝试写操作 如果shell和终端驱动程序是按通常情况配置的话,在键盘上敲入中断字符(Ctrl+C)就会向前台(即当前正在执行的程序)发生sigint信号,这将引起该
进程的终止,除非它事先安排了捕获这个信号。 如果想发送一个命令给进程,但该进程不是当前的前台进程,就需要使用kill命令,该命令需要
一个可选的信号代码或信号名称和
一个接受信号的目标进程的PID(pid一般需要ps命令查看)
kill -- 发送一个命令给一个进程,常用的信号包括HUP,INT,KILL,STOP,CONT,0. 程序可以使用signal库函数来处理信号,
#include <signal.h>
void (*signal(int sig,void (*func)(int)))(int);
signal是一个带有sig和func两个参数的函数;
准备捕获/忽略的信号有参数sig给出,接受到指定的信号后将要调用的函数由参数func给出,
信号处理函数必须有一个int类型的参数(即接收到的信号代码)并且返回类型为void,
signal函数本身也返回一个同类型的函数,即先前用来处理这个信号的函数(不是func函数);
返回的是先前对指定信号进行处理的信号处理函数的函数指针,如果未定义信号处理函数,则返回SIG_ERR,并设置errno为一个正整数值,
如果给出的是一个无效的信号,或者尝试处理的信号不可捕获/不可忽略(如SIGKILL),errno将被设置为EINVAL。
也可以使用特殊值(sig_ign,sig_dfl)来代替信号处理函数;
sig_ign 忽略信号
sig_dfl 恢复默认信号 -----------------------
信号处理例子:编写一个程序ctrlc.c,来响应用户敲入的Ctrl+c组合键,在屏幕上打印一条适当的消息而不是终止程序的运行;再次ctrl+c时,结束。
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void ouch(int sig)
{
printf("ouch! - I got signal %d\n",sig);
(void) signal(SIGINT,SIG_DFL);
} int main(){
(void) signal(SIGINT,ouch); while(){
printf("hello world\n");
sleep();
}
}
main()的作用是捕获ctrl+c产生的SIGINT信号,没有信号产生时,它会在一个无限循环中打印字符;
(void) signal(SIGINT,ouch),在捕获SIGINT信号后,会调用ouch函数进行处理;
(void) signal(SIGINT,SIG_DFL),再次捕获SIGINT信号,SIG_DFL来恢复信号的默认行为;
------------
发送信号
进程可以通过调用kill函数将包括它在内的其他进程发送一个信号,如果程序没有发送该信号的权限,对kill函数的调用就会失败;
失败的常见原因,是目标进程由另一个用户所拥有;
#include<sys/types.h>
#include<signal.h>
int kill(pid_t pid,int sig);
kill函数吧参数sig给定的信号发送给参数pid给出的进程号所指定的进程,成功时它返回0;
kill调用失败返回-1并设置errno变量,
失败原因:
给定的信号无效 errno = EINVAL
发送权限不够 errno = EPERM
目标进程不存在 errno = ESRCH
--
信号的闹钟功能,进程可以通过调用alarm()在经过预定时间后发送一个sigalrm信号,
#include<unistd.h>
unsigned int alarm(unsigned int seconds);
/*************************************************************************
> File Name: alarm.c
> Author:
> Mail:
> Created Time: 2016年03月26日 星期六 12时30分10秒
************************************************************************/ #include<stdio.h>
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h> static int alarm_fired = ; void ding(int sig){
alarm_fired = ;
} int main(){
pid_t pid;
printf("alarm application starting\n"); pid = fork();
switch(pid){
case -:
//failure
perror("fork failed");
exit(); case :
//child
printf("It is a child process, and it will sleep 5s\n");
printf("child process Pid = %d\n",getpid());
sleep();
printf("5s has past, child process will generate a sigalrm\n");
kill(getppid(),SIGALRM);
printf("child process has generated a sigalrm signal\n");
exit();
} //if we get here ,we are the parent process
printf("it is a parent process, it pId = %d\n",getpid());
printf("waiting for alarm to go off \n");
(void) signal(SIGALRM,ding); pause();
if(alarm_fired)
printf("Ding!\n"); printf("done\n");
exit();
}
执行结果:
lizhen@lizhen:~/basic$ ./a.out
alarm application starting
it is a parent process, it pId =
waiting for alarm to go off
It is a child process, and it will sleep 5s
child process Pid =
5s has past, child process will generate a sigalrm
child process has generated a sigalrm signal
Ding!
done
 
---
getpid,getppid --get process identification
#include <sys/types.h>
#include <unistd.h> pid_t getpid(void)
pid_t getppid(void)
getpid() return the process ID of the calling process(this is often used by routines
that generate unique temporay filenames.)
getppid() returns the process ID of the parent of the calling process.
----
pause -wait for signal
#include <unstd.h>
int pause(void)
pause() causes the calling process (or thread) to sleep until a signal
is delivered that either terminates the process or causes the invocation of a signal-catching
function.就是程序的执行挂起直到有一个信号出现为止,当程序接受到一个信号时,预设好的信号处理函数将开始运行,程序也恢复
正常的执行。当它被一个信号中断是,将返回-1(如果下一个接受到的信号没有导致程序终止的话)并把errno设为EINTR,
当需要等待信号时,一个更常见的做法就是使用sigsuspend函数; ===
使用信号并挂起程序的执行是linux程序设计的一个重要部分,意味着程序不需要总是在执行着;
程序不必在一个循环中无休止地检查某个事件是否已发生,他可以等待事件的发生。
这在只有一个cpu的多用户环境中很重要;
进程共享着一个cpu,繁忙的等待将会对系统的性能造成很大的影响。
一个特殊的问题,“如果信号出现在系统调用的执行过程中会发生什么情况?”
在编写程序中处理信号部分的代码时,应该非常小心,因为在使用信号的程序中会出现各种“竞态条件“,
例如,想调用pause等待一个信号,可信号却出现在调用pause之前,就会使程序无限期地等待一个不会发生的时间。
这些竞态条件都是一些对时间要求很苛刻的问题,所以在检查和信号相关的代码时总会非常小心; ---
一个健壮的信号接口
sigaction
#include<signal.h>
int sigaction(int sig,const struct sigaction *act,struct sigaction *oact);
sigaction结构定义在文件signal.h中,作用是定义接受到sig指定的信号后应该采取的动作;

[linux basic]基础--信号的更多相关文章

  1. [linux basic基础]----套接字

    套接字是一种通信机制,凭借这种机制client/server系统的开发者既可以在本地机器上进行,也可以跨网络进行. 1,服务器应用程序用系统调用socket来创建一个套接字,他是系统分配给服务器进程的 ...

  2. [linux basic 基础]----线程的属性

    在信号量和互斥量例子中,我们都是在程序推出之前利用pthread_join对线程进行再次同步:如果想让thread想创建它的线程返回数据我需要这么做:问题:我们有时候既不需要第二个线程向main线程返 ...

  3. [linux basic 基础]----同步互斥量

    互斥量,运行程序元锁住某个对象,使得每次只能有一个线程访问它:为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它 :基本函数与用于信号量的函数非常相似#inclu ...

  4. [linux basic 基础]----同步信号量

    直接使用一个共享变量,来是两个线程之间进行切换是非常笨拙而且没有效率的:信号量--互斥量--这两者是相互通过对方来实现的:比如,如果想控制某一时刻只有一个线程可以访问一些共享内存,使用互斥量要自然一些 ...

  5. [WPF系列]-基础 TextBlock

    AUTOMATICALLY SHOWING TOOLTIPS ON A TRIMMED TEXTBLOCK (SILVERLIGHT + WPF)

  6. [Swift]基础

    [Swift]基础 一, 常用变量 var str = "Hello, playground" //变量 let str1="Hello xmj112288" ...

  7. Linux 的使用基础---Linux的常用命令

    自己电脑的安装的软件太多了,如果重装linux系统的话,是在是太麻烦了,本身电脑系统是32位的,硬件上的配置也行,所以就安装了虚拟机,在虚拟机上又安装了一个Linuxd 系统,虽然速度是有些慢,总比浪 ...

  8. Linux环境进程间通信(二): 信号(上)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  9. Linux 高性能服务器编程——Linux网络编程基础API

    问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字(so ...

随机推荐

  1. 获取验证码,60秒倒计时js

    <input type="button" id="btn" value="免费获取验证码" /><script type= ...

  2. 整理的一些免费的Android项目实战系列视频教程

    http://blog.itpub.net/29737144/viewspace-1212539/

  3. Android——AutoCompleteTextView、Spinner和消息提示

    layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  4. poj3660 最短路/拓扑序

    题意:有n头牛,为了给牛排顺序,给出了牛之间的胜负关系,具有传递性,问给出的胜负关系是否可以给这些牛排出唯一的顺序. 其实是个拓扑排序问题,牛的胜负关系就是有向边,然后判断是否有唯一的拓扑序就行.当然 ...

  5. Linux系统编程@多线程与多进程GDB调试

    博客内容参考自 http://www.cnblogs.com/xuxm2007/archive/2011/04/01/2002162.html http://blog.csdn.net/pbymw8i ...

  6. php mcrypt 完全安装

    今天安装完 PHP ,访问某个功能时,  /var/log/httpd/error_log  中报如下错误: PHP Fatal error:  Call to undefined function ...

  7. NETMON& Message Analyzer

    NMCap /network * /capture  /file c:\folder\t.chn:1MB NMCap /network * /capture (IPv4.SourceAddress = ...

  8. Linux下编译使用boost库:

    Boost是什么不多说, 下面说说怎样在Linux下编译使用Boost的所有模块. 1. 先去Boost官网下载最新的Boost版本, 我下载的是boost_1_56_0版本, 解压. 2. 进入解压 ...

  9. Python3下map函数的显示问题

    map函数是Python里面比较重要的函数,设计灵感来自于函数式编程.Python官方文档中是这样解释map函数的: map(function, iterable, ...) Return an it ...

  10. python datetime

    不管何时何地,只要我们编程时遇到了跟时间有关的问题,都要想到 datetime 和 time 标准库模块,今天我们就用它内部的方法,详解python操作日期和时间的方法.1.将字符串的时间转换为时间戳 ...