做网站要哪些技术,制作网站需要多少钱,学校网站设计制作目的,中铁建设企业门户一 . 信号1. 信号#xff1a;是内核发送给某一进程的一种消息 。2. 信号机制#xff1a;是Linux系统中用于进程之间相互通信或操作的一种机制。3. 信号的来源#xff1a;信号来源于内核4. 产生原因#xff1a; (1)用户通过终端输入 (2)进程执行(3)一个进程调用kill向另一个…一 . 信号1. 信号是内核发送给某一进程的一种消息 。2. 信号机制是Linux系统中用于进程之间相互通信或操作的一种机制。3. 信号的来源信号来源于内核4. 产生原因 (1)用户通过终端输入 (2)进程执行(3)一个进程调用kill向另一个进程发送信号5. 信号分类1)同步信号 异步信号2)可靠信号 : 信号被递送多次 不可靠信号: 只被递送一次的信号6. 信号处理方式A. 按系统默认方式处理 ——每个信号都有一个默认动作典型的默认动作是终止进程。 man signal 7 列出系统对各信号的默认处理 。B. 忽略信号——接收信号但是不做任何操作 。C. 捕捉信号——程序提前告诉内核当信号到来时应该调用哪个函数。二. 信号相关函数1. 简单的信号处理函数原型 sighandler_t signal(int signum, sighandler_t handler);参 数signum ——要响应的信号handler ——信号发生时要执行的操作。返回值非-1 执行成功返回以前的信号处理函数指针-1 遇到错误//捕捉信号#include #include #include #include void capture(int signum){printf(SIGINT is capture!\n);}int main(int argc, char *argv[]){int i10;if(signal(SIGINT,capture) SIG_ERR){printf(Cant catch SIGINT);exit(1);}printf(waiting for signal...\n);while(i 0){printf(Now i%d \n,i);sleep(1);i--;}return 0;}//忽略信号#include #include #include int main(int argc,char *argv[]){int i10;signal(SIGINT,SIG_IGN);printf(waiting for signal ...\n);while(i 0){sleep(1);i--;printf(Now i %d,but you cant stop this program by Ctrl C\n,i);}return 0;}//恢复信号的默认处理#include #include void capthensfl(int signum){printf(SIGINT is capture !\n);signal(SIGINT,SIG_DFL);printf(SIGINT now is defaulted !\n);}int main(int argc,char *argv[]){int i10;signal(SIGINT,capthensfl);printf(waiting for signal...\n);while(i 0){sleep(1);printf(Now i %d\n,i);i--;}return 0;}2. 信号处理函数指定一个信号的处理函数函数原型int sigaction(int signum, struct sigaction *action, struct sigaction *oldaction);参 数signum 要处理的信号action 要安装的信号处理操作的结构oldaction 之前的信号处理操作的结构返回值0 成功 -1失败说 明oldaction不为NULL则用其来存储以前设置的与此信号关联的操作。action不为NULL 则指定信号关联的操作为此参数指向的结构 否则信号处理保持不变。(此方式用来查询当前对指定信号的处理方式)sigaction的结构struct sigaction{union{ __sighandler_t _sa_handler;void(*_sa_sigaction)(int , struct siginfo *, void *);} __u;sigset_t sa_mask;unsigned long sa_flags;};sa_sigaction的说明 void (*sa_sigaction)(int, struct siginfo *void *);第一个参数要响应的信号 。第二个参数记录导致产生信号的原因、类型等 。第三个参数信号发生时被中断的上下文环境 信号能传递简单的信息。//使用sa_sigaction类型函数#include #include #include #include void fun(int signo, siginfo_t *info, void *context){printf(Test for sa_sigaction !\n);}int main(int argc,char *argv[]){struct sigaction action,oldaction;sigemptyset(action.sa_mask);action.sa_flagsSA_SIGINFO;action.sa_sigactionfun;sigaction(SIGINT,action,oldaction);printf(waiting for signal...\n);while(1){pause();}return 0;}3. 初始化信号集函数原型int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);参 数set 待初始化的信号集返回值0 成功 -1失败4. 添加、删除信号函数原型int sigaddset(sigset_t *set, int signo);int sigdelset(sigset_t *set, int signo);参 数set 待初始化的信号集 . signo 待添加/删除的信号编号返回值0 成功 -1失败5. 修改屏蔽信号集函数原型int sigprocmask(int how,sigset_t *set, sigset_t * oldset);参 数how 如何修改信号掩码set 要使用的信号集oldset 之前的信号集返回值0 成功 -1失败对参数how的说明: SIG_BLOCK信号集中增加set中的信号SIG_UNBLOCK信号集中删除set中的信号SIG_SETMASK信号集被设置为set信号集三. 系统调用函数1. kill —— 向进程发送一个信号函数原型int kill(pid_t pid, int sig);参 数pid 目标进程id sig 要发送的信号返回值0 成功 -1失败说 明 pid0 目标进程的进程号为pidpid0 将信号发送给和当前进程在同一进程租的所有进程pid-1 将信号发送给系统内的所有进程pid0 将信号发送给进程组号PGID为pid绝对值的所有进程一个进程可使用kill函数将信号发送给另一进程或进程组。要求发送信号的进程的用户ID和目标进程的用户ID相同或发送信号的进程的owner是一个超级用户。//kill 使用示例#include #include #include void fun(int signo){printf(Process capture SIGINT);signal(SIGINT,SIG_DFL);}int main(int argc,char *argv[]){int pid;if((pidfork()) -1){perror(fork);exit(EXIT_FAILURE);}else if( pid 0){signal(SIGINT,fun);printf(Child %d waiting for parent %d send signal\n,getpid(),getppid());pause();pause();}else{sleep(1);printf(Parent %d will send signal to child %d \n,getppid(),getpid());kill(pid,SIGINT);wait(NULL);}return 0;}2. raise —— 自举一个信号函数原型int raise(int signo);参 数signo 待发送的信号返回值0 成功 -1失败说 明raise(signo)kill(getpid(),signo)3. alarm —— 设置计时器函数原型int alarm(int seconds);参 数seconds 计时的秒数返回值 0 之前未调用过alarm0 之前调用alarm设置的闹钟时间的余留秒数4. pause —— 挂起调用进程函数原型int pause(void);返回值-1 并将errno设置为EINTR四. 信号集合操作应用示例/* 信号的应用示例父进程执行文件复制操作如果收到SIGUSR1信号就打印出当前的复制进度子进程每隔一个固定时间向父进程发送SIGUSR1信号*/#include #include #include #include #include #include int count; //当前复制大小int file_size; //文件的大小//父进程对SIGUSR1信号的处理函数void sig_usr(int signum){float i;//求出复制进程i (float)count/(float)file_size;printf(current over : %0.0f%%\n,i*100);}//子进程对SIGUSR1信号的处理即向父进程发送SIGUSR1信号void sig_alarm(int signo){kill(getppid(),SIGUSR1);}//主函数int main(int argc ,char *argv[]){pid_t pid;int i;int fd_src,fd_des;char buf[128];if(argc ! 3){printf(the format must be : command src_file des_file \n);return -1;}//以只读方式打开源文件if((fd_src open(argv[1],O_RDONLY)) -1){perror(open fd_src);exit(EXIT_FAILURE);}//获取源文件大小file_size lseek(fd_src,0,SEEK_END);//重新设置读写位置为文件头lseek(fd_src,0,SEEK_SET);//以读写方式打开目标文件如果不存在就创建if((fd_des open(argv[2],O_RDWR|O_CREAT,0644)) -1){perror(open fd_des);exit(EXIT_FAILURE);}//进程创建失败if((pid fork() -1)){perror(fork);exit(EXIT_FAILURE);}//父进程else if(pid 0){//安装信号signal(SIGUSR1,sig_usr);do{memset(buf,\0,128);//复制数据if((i read(fd_src,buf,1)) -1){perror(read);exit(EXIT_FAILURE);}//如果复制完成向子进程发送SIGINT信号终止else if(i 0){kill(pid,SIGINT);break;}else{//执行复制操作if(write(fd_des,buf,i) -1){perror(write);exit(EXIT_FAILURE);}count i; //更新已经复制的文件的大小}}while(i ! 0);//等待子进程退出wait(pid,NULL,0);exit(EXIT_SUCCESS);}//子进程else if(pid 0){usleep(1);signal(SIGALRM,sig_alarm);ualarm(1,1);while(i){;}exit(EXIT_SUCCESS);}return 0;}