Linux操作系统——信号通信

实验题目:信号通信


实验前置知识:
信号处理函数:
(1)信号安装函数
signal()函数示例:

	#include"signal.h"/使用两个函数都必须包含这个头文件
	#include"unistd.h"
	#include"stdio.h"
	//信号处理函数,调用时参数dunno会得到信号的值
	void sigroutine(int dunno){
	        switch(dunno){
	        case 1:printf("Git a signal-SIGHUP\n");break;
	        case 2:printf("Git a signal-SIGINT\n");break;
	        case 3:printf("Git a signal-SIGQUIT\n");break;
	        }
	        return;
	}
	int main(){
	        printf("process id is %d\n",getpid());
	        //下面设置了3个信号处理函数
	        signal(SIGHUP,sigroutine);		//通过kill操作得到Git a signal-SIGHUP
	        signal(SIGINT,sigroutine);		//通过Ctrl+C得到Git a signal-SIGINT
	        signal(SIGQUIT,sigroutine);		//通过Ctrl+\得到Git a signal-SIGQUIT
	        for(;;);
	}
	//kill -9 31658  可以终止进程

操作结果:
在这里插入图片描述
sigaction()函数示例:

	#include"signal.h"//使用两个函数都必须包含这个头文件
	#define PROMPT"你想终止程序吗"
	char *prompt=PROMPT;
	void ctrl_c_op(int signo){
	        write(STDERR_FILENO,prompt,strlen(prompt));
	}
/*
	int sigaction(int signum,const struct sigaction *act.struct sigaction *oact);
	struct sigaction{
	        void (*sa_handler)(int signum);
	        void (*sa_sigaction)(int siginfo_t *info,void *act)
	        sigset_t sa_mask;
	        int sa_flags;
	        void(*sa_restore)(void);
	}
*/
	int main(){
        struct sigaction act;
        act.sa_handler=ctrl_c_op;
        sig.sa_flags=0;
        if(sigaction(SIGINT,&act,NULL)<0){
                fprintf(stderr,"Signal Action Error:%s\n\a",strerror(errno));
                return 0;
        }
        while(1);
	}

(2)信号发送函数
必须包含的头文件
#include<sys/types.h>
#include<signal.h>

kill()函数:
int kill(pid_t pid,int sig);
若pid>0,信号sig发送给进程号为pid的进程
若pid=0,信号sig发送给当前进程所属的进程组里的所有进程
若pid=-1,信号sig发送给除了号进程和自身以外的所有进程
若pid<-1,信号sig发送给属于进程组 -pid 的所有进程
若sig=0,将不发送信号
返回值为0时,函数执行成功
返回值为-1时,错误 错误代码error
error=EINVAL,信号sig无效
error=SRCH,pid指定的进程不存在
error=EPERM,权限不足

raise()函数:
用于向自身发送信号
int raise(sint sig);
raise(signo)=kill(getpid(),signo)

alarm()函数:
用于设置一个定时器,时间到则发送SIGALRM信号给进程
unsigned int alarm(unsigned int seconds);

setitimer()函数:
定时器

pause()函数:
是当前进程暂停进入睡眠状态,直到被信号所中断
int pausee(void)

(3)信号操作函数

int sigemptyset(sigset_t *set);
初始化信号量集合set,将set设置为空

int sigfillset(sigset_t *set);
初始化信号量集合,将信号量集合设置为所有信号的集合
int sigfaddset(sigset_t *set,int signo);
将信号signo加入到信号集合之中
int sigdelset(sigset_t *set,int signo);
将信号从信号集合中删除
int sigmember(sigset_t *set,int signo);
查询信号是否在信号集合中
最关键信号
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
先设置号信号集合set,将指定的信号集合set加入到进程的信号阻塞集合中去


附上实验报告

实验题目:信号通信
实验目的:本实验的目的主要是使学生理解信号概念、掌握信号通信机制及借此实现Linux进程间通信的原理。
实验要求:利用信号通信机制在父子进程及兄弟进程间进行通信。
实验内容:

1.编写程序,实现阻塞型通信。

源程序:

#include"unistd.h"
#include"sys/types.h"
#include"signal.h"
#include"wait.h"
void sigchild_handler(int sig)
{
        pid_t pid;
        int status;
        for(;(pid=waitpid(-1,&status,WNOHANG))>0;)
        {
                printf("child:%ddied:%d\n",pid,WEXITSTATUS(status));
                printf("hi,parent process received SIGHLD signal successfully!\n");
        }
        return;
}

int main()
{
        int pc;
        pc=fork();
        if(pc==0)
        {
                printf("child process pid%d!\n",getpid());
                sleep(3);
                return 0;
        }
}

执行流程:

[2016236153@localhost ~]$ vi barrage.c
[2016236153@localhost ~]$ gcc -o barrage barrage.c
[2016236153@localhost ~]$ ./barrage
child process pid19408!
child:19408died:0
hi,parent process received SIGHLD signal successfully!
[2016236153@localhost ~]$ 

运行结果:
在这里插入图片描述

2.编写程序,实现非阻塞型通信

源程序:

#include"signal.h"
#include"stdlib.h"

void sigint_handler(int sig){
        printf("received SIGINT signal successed!\n");
        return;
}

void main(){
        int pc;
        pc=fork();
        if(pc==0){
                printf("this is child process pid %d\n",getpid());
                sleep(3);
                printf("this is child process pid first sleep %d\n",getpid());
                sleep(3);
                printf("this is child process pid second sleep %d\n",getpid());
        return;
        }else if(pc>0){
                signal(SIGINT,sigint_handler);
                pause();
        }else if(pc<0){
                printf("Error!\n");
                return;
        }
}

执行流程:

[2016236153@localhost ~]$ vi unbarrage.c
[2016236153@localhost ~]$ gcc -o unbarrage unbarrage.c
[2016236153@localhost ~]$ ./
aa*           barrage1*     dsl/          memos/        unbarrage*
b*            barrage2*     hello*        q*
barrage*      dengshenglin/ lab8*         sigmaltest*
[2016236153@localhost ~]$ ./unbarrage
this is child process pid 19108
this is child process pid first sleep 19108
this is child process pid second sleep 19108
^Creceived SIGINT signal successed!
[2016236153@localhost ~]$ bg
bg: No current job.

运行结果:
在这里插入图片描述

发布了26 篇原创文章 · 获赞 39 · 访问量 5119

猜你喜欢

转载自blog.csdn.net/DengShengL/article/details/91128800
今日推荐