linux 异步通知机制,Linux开发——Signal异步通知机制

目录

目标:

实战:

Linux中的信号

信号的基本操作

相关函数

信号集合操作

未决信号

目标:

如何发起异步操作(对本身发起,对其他进程发起)

如何安装信号

如何屏蔽和管理信息

如何利用信号进行阻塞操作

实战:

信号驱动的服务器

电报机

Linux中的信号

信号 取值 默认动作 含义(发出信号的原因)

SIGHUP 1 Term 终端的挂断或进程死亡

SIGINT 2 Term 来自键盘的中断信号

SIGQUIT 3 Core 来自键盘的离开信号

SIGILL 4 Core 非法指令

SIGABRT 6 Core 来自abort的异常信号

SIGFPE 8 Core 浮点例外

SIGKILL 9 Term 杀死

SIGSEGV 11 Core 段非法错误(内存引用无效)

SIGPIPE 13 Term 管道损坏:向一个没有读进程的管道写数据

SIGALRM 14 Term 来自alarm的计时器到时信号

SIGTERM 15 Term 终止

SIGUSR1 30,10,16 Term 用户自定义信号1

SIGUSR2 31,12,17 Term 用户自定义信号2

SIGCHLD 20,17,18 Ign 子进程停止或终止

SIGCONT 19,18,25 Cont 如果停止,继续执行

SIGSTOP 17,19,23 Stop 非来自终端的停止信号

SIGTSTP 18,20,24 Stop 来自终端的停止信号

SIGTTIN 21,21,26 Stop 后台进程读终端

SIGTTOU 22,22,27 Stop 后台进程写终端

SIGBUS 10,7,10 Core 总线错误(内存访问错误)

SIGPOLL Term Pollable事件发生(Sys V),与SIGIO同义

SIGPROF 27,27,29 Term 统计分布图用计时器到时

SIGSYS 12,-,12 Core 非法系统调用(SVr4)

SIGTRAP 5 Core 跟踪/断点自陷

SIGURG 16,23,21 Ign socket紧急信号(4.2BSD)

SIGVTALRM 26,26,28 Term 虚拟计时器到时(4.2BSD)

SIGXCPU 24,24,30 Core 超过CPU时限(4.2BSD)

SIGXFSZ 25,25,31 Core 超过文件长度限制(4.2BSD)

SIGIOT 6 Core IOT自陷,与SIGABRT同义

SIGEMT 7,-,7 Term

SIGSTKFLT -,16,- Term 协处理器堆栈错误(不使用)

SIGIO 23,29,22 Term 描述符上可以进行I/O操作

SIGCLD -,-,18 Ign 与SIGCHLD同义

SIGPWR 29,30,19 Term 电力故障(System V)

SIGINFO 29,-,- 与SIGPWR同义

SIGLOST -,-,- Term 文件锁丢失

SIGWINCH 28,28,20 Ign 窗口大小改变(4.3BSD, Sun)

SIGUNUSED -,31,- Term 未使用信号(will be SIGSYS)

信号的基本操作

发送信号    kill -x pid      函数:int kill(pid,signum)

捕获信号   signal(signum,函数)== SIG_ERR

忽略信号   signal(signum,SIG_IGN)

相关函数

pause()使调用进程(或线程)进入休眠状态,直到传递的信号终止进程或导致调用信号捕获函数。

alarm(4)定时器,4s后返回  重复使用会让上一个定时器返回,返回内容是剩余时间 发送SIGALRM信号

ualarm(5000000,2000000) 第一5s返回  之后2s返回一次   发送SIGALRM信号(注:该函数多次实验,均未成功)

int getitimer(int which,struct itimerval * curr_value);

int setitimer(int which,const struct itimerval * new_value,struct itimerval(old_value);

ITIMER_REAL    根据系统时间递减

ITIMER_VIRTUAL   根据程序执行时间递减

ITIMER_PROG    进程执行,系统调用的时候才递减

struct itimerval

{struct itmerval it_interval   //间隔值

struct itmerval in_value //第一次值}

struct itmerval

{time_t   tv_sec;                  s单位

suseconds_t  tv_usec ;           mincroseconds 微秒为单位}

int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);

struct sigaction

void (*sa_handler)(int)         和参数2    二选一

void (*sa_sigaction)(int ,siginfo_t *,void *);

sigset_t  sa_mask;     信号屏蔽集合

//清空信号sigemptyset(&act.sa_mask);添加sigaddset(&s,SIGUSR1);sigfillset

int  sa_flags;              接受标志 //接收数据时  需要设置sa_flags = SA_SIGINFO

void  (*sa_restorer)(void);

sigset_t   信号集合

SA_SIGINFO

siginfo_t{

int    si_signo     信号number

int    si_errno       错误值

int     si_code

int      si_trapno}

pid     si_pid

........

union    sigval_t {

int sival_int;

void * sival_ptr}

sigqueue(pid,signum,union sigval aaa)发送信号到指定pid  并且传递一个参数

信号集合操作

int sigemptyset(sigset_t *set);

int sigfillset (sigset *set);

int sigaddset(sigset *set,int signum);

int sigdelset(sigset *set,int signum);

int sigismember(const sigset_t *set,int signum);   判断是否存在

设置屏蔽信号集合

int sigprocmask(int how,const sigset_t *set,sigse_t *oldset);设置set为屏蔽信号

SIG_BLOCK设置信号阻塞方式     SIG_UNBLOCK非阻塞    SIG_SETMASK设置为屏蔽集

未决信号

sigpending(sigset *set);

//查看未决信号中有哪些信号

void print_sig(sigset_t *p)

{

int i=1;

for(;i<32;i++){

if(sigismenmber(p,i)){

printf("1");

}else {

printf("0");

}

}

printf("\n");

}

sigsuspend(strcut sigset_t *set)   等待信号函数  接收到一个信号  不在set中 该函数返回

简单例子:

#include "stdio.h"

#include #include "signal.h"

#include "errno.h"

#include #include #include #include union sigval val;

pid_t pid;

void showprogress(int a, siginfo_t * info, void * data){

printf("file copy progress:%d\n", info->si_value.sival_int);

if((info->si_value.sival_int) >1000)

{

printf("file copy sucess!!!\n");

exit(0);

}

}

void sendsigusr1(int pro)

{

union sigval haha;

haha.sival_int =100;

val.sival_int = 100;

sigqueue(pid,SIGUSR1,haha);

}

int main(int argc,char*argv[])

{

int readfile,writfile;

int filesize = 0;

if(argc<3)

{

printf("please stdin enter file name : readfile writfile...");

exit(0);

}

pid = fork();

if(pid==-1){

perror("fork error");

exit(0);

}else if(pid == 0)

{

struct sigaction act;

printf("haha\n");

act.sa_flags = SA_SIGINFO;

act.sa_sigaction = showprogress;

sigemptyset(&(act.sa_mask));

sigaction(SIGUSR1,&act,NULL);

while(1){

printf("chlid is runing!\n");

pause();

}

}else if(pid>0){

int progress = 0;

int i = 0;

char buf[8];

val.sival_int = 0;

if((readfile = open(argv[1],O_RDWR))==-1)

{

perror("open");

exit(0);

}

if ((writfile = open(argv[2],O_RDWR|O_CREAT))==-1)

{

/* code */perror("open");

exit(0);

}

filesize = lseek(readfile,0,SEEK_END);

lseek(readfile,0,SEEK_SET);

signal(SIGALRM,sendsigusr1);

//ualarm(1,1);

while(1)

{

i = read(readfile,buf,1);

if(i <=0) {

close(readfile);

close(writfile);

break;

}

progress+=i;

write(writfile,buf,1);

val.sival_int = progress;

sigqueue(pid,SIGUSR1,val);

}

close(readfile);

close(writfile);

val.sival_int = -666;

sigqueue(pid,SIGUSR1,val);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值