计算机操作系统—信号

一、基本概念

1.中断

中断是暂停当前执行的任务,转而执行其它任务,带完成后再返回当前任务。
硬件中断:来自硬件设备的中断
软件中断:来自其它程序的中断
信号就是一种软件中断,为操作系统提供一种异步执行任务的机制

2.信号的种类

1. 不可靠信号
不可靠信号是一种早期的信号机制 ,在操作系统中小于(34)SIGRTMIN的都是不可靠信号。
这些信号不支持排队,可能会丢失。同一个信号如果产生多次,进程只会收一次。

2.可靠信号
可靠信号是位于(34)SIGRTMIN和(64)SIGRTMAX之间的信号,
这些信号支持排队且不会丢失,安全可靠。
3.常见的信号
SIGSEGV(11) 段错误信号 试图访问未映射过的虚拟内存,或向没有写权限的内存写入数据时 终止+core
SIGINT(2) 终端中断信号,用户可以按中断键(Ctrl + c),产生此信号,并送至前台进程组的所有进程 终止
SIGFPE(8) 算术异常信号 表示一个算术运算异常,例如除以0、浮点溢出等 终止+core

信号的默认处理方式:终止、终止+core、忽略

3.信号的来源

硬件异常:硬件(驱动)检测到一个错误条件并通知内核,随机再由内核发送相应信号给相关进程,进程收到信号后作出相应的响应。例如:除0、无效的内存访问等。

软件异常:通过一些函数、命令产生的信号,例如:针对文件描述符的输出变为有效,调整了终端窗口大小,定时器到期,进程执行的CPU时间超限,或者该进程的某个子进程退出等。

二、信号的捕获处理

1.现在内核中注册一个信号处理函数
2.当信号发生时内核会捕获信号并调用信号处理函数

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum,sighandler_t handler);
/*
功能:向内核注册一个信号处理函数
signum:要捕获的信号
handler:
	1.信号处理函数的地址
	2.SIG_IGN(忽略) SIG_DFL(按默认方式处理)
返回值:成功返回该信号原来的处理方式(函数指针或SIG_IGN SIG_DFL)
*/

注意:SIGKILL(9)终止信号,SIGSTOP(19)停止信号,这两个信号既不能被捕获也不能被忽略。

三、发送信号

1、键盘
Ctrl+c SIGINT(2) 终端中断
Ctrl+\ SIGQUIT(3) 终端退出
Ctrl+z SIGSTP(20) 终端暂停

2、代码错误
除0 SIGFPE(8) 算术异常信号 
非法访问内存 SIGSEGV(11) 段错误信S号 
硬件故障 SIGBUS(7) 总线错误信号 

3、命令
kill -信号 进程号
killall -9 CMD	杀死所有名叫cmd的进程

4、函数
int kill(pid_t pid, int sig);
功能:向指定的进程发送指针的信号

int raise(int sig);
功能:进程向自己发送sig信号。

四、进程休眠

int pause(void);
功能:使调的进程进入休眠状态,直到遇到信号且信号处理函数结束后才返回。
返回值:要么永远不返回,要么被信号中断返回-1。

unsigned int sleep(unsigned int seconds);
功能:使调用的进程休眠seconds秒,当信号发生时会提前结束。
返回值:0(睡够了)或剩余的秒数。

五、闹钟信号

unsigned int alarm(unsigned int seconds);
功能:在seconds秒后向调用的进程发送闹钟信号,该信号的默认处理方式是终止进程。
seconds:如果为0,则相当于取消闹钟信号。
返回值:上次设置的闹钟信号,还有多少秒产生。

六、信号集与信号屏蔽

1、信号集:多个信号的集合,类型sigset_t 128位二进制,每一位代表一个信号。
int sigemptyset(sigset_t *set);
功能:设置信号集中所有二进制位为0

int sigfillset(sigset_t *set);
功能:设置信号集中所有二进制位为1

int sigaddset(sigset_t *set, int signum);
功能:向信号集中添加信号

int sigdelset(sigset_t *set, int signum);
功能:从信号集中删除信号

int sigismember(const sigset_t *set, int signum);
功能:判断信号集中是否有某个信号

2、信号屏蔽
信号屏蔽掩码(信号集):里面记录着当前进程不想收到的信号
int sigprocmask(int how, const sigset_t *set,sigset_t *oldset);
功能:设置当前进程的信号屏蔽掩码
how:修改信号掩码的方式
    SIG_BLOCK   把参数set中的信号添加到信号屏蔽码中
    SIG_UNBLOCK 把参数set中与信号屏蔽码中交集的信号删除
    SIG_SETMASK 把参数set中信号拷贝到信号屏蔽码中
set:NULL则忽略,表示只想获取当前进程的信号屏蔽码
oldset:存储当前进程的信号屏蔽码
注意:当信号屏幕码还原时,未决状态的信号会再次发生,继续递送,不可靠信号只递送一次,而可靠信号排队递送。

int sigpending(sigset_t *set);
功能:获取当前进程未决状态的信号。

六、带参数的信号处理

int sigaction(int signum, const struct sigaction *act,
                 struct sigaction *oldact);
功能:向内核注册信号和处理方式
act:信号处理方式
oldact:旧的信号处理方式

struct sigaction {
    void     (*sa_handler)(int);  // 普通的信号处理函数,与signal的一样
    void     (*sa_sigaction)(int, siginfo_t *, void *); //带参数的信号处理函数
    sigset_t   sa_mask; // 信号屏蔽码
    int        sa_flags;
    void     (*sa_restorer)(void);
};
sa_flags:
    SA_RESETHAND/SA_ONESHOT 当信号处理完后,恢复默认的信号处理方式。
    SA_NOCLDSTOP  如果信号是 SIGCHLD,当子进程暂停时不通知父进程。
    SA_NODEFER/SA_NOMASK 在信号处理函数执行过程中不屏蔽当前正在处理的信号。
    SA_RESTART 如果系统调用被该信号中断,会自动重启。
    SA_SIGINFO 使用sa_sigaction来处理信号

int sigqueue(pid_t pid, int sig, const  union  sigval
   value)
功能:向指定的进程发送sig信号,附加value(整数或指针)。
返回值:成功返回0,失败返回-1;

七、计时器

系统为每个进程维护三个计时器
	真实计时器:程序运行的实际时间
	虚拟计时器:程序运行在用户态所消耗的时间
 	实用计时器:程序运行在用户太和内核态所消耗的时间之和
	实际用时(真实计时器)=用户时间(虚拟计时器)+内核时间+睡眠时间

int getitimer(int which, struct itimerval *curr_value);
功能:获取计时器的设置
which:计时器类型
    ITIMER_REAL     真实计时器 SIGALRM
    ITIMER_VIRTUAL  虚拟计时器 SIGVTALRM
    ITIMER_PROF     实用计时器 SIGPROF
返回值:成功返回0,失败返回-1。

struct itimerval {
    struct timeval it_interval; 每隔多久产生一次时钟信号
    struct timeval it_value;    第一次产生时钟信号的时间
};

struct timeval {
    long tv_sec;    秒
    long tv_usec;   微秒 1=1000000  // 不能超过1000000   
};


int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
功能:设置计时器
which:计时器类型
new_value:新的计时方案
old_value:旧的计时方案,也可以为NULL

注意:与alarm函数的效果基本一致,但使用计时器更精细,但准确。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PV操作是指操作系统中用于进程通信和同步的一种机制。信号量(Semaphore)是一种计数器,用于控制对共享资源的访问。它具有两个基本操作:PV操作。PV操作也被分为两个部分:P操作和V操作。 P操作(Wait操作)用于申请资源。当进程需要使用一个共享资源时,它会尝试对信号量进行P操作。如果信号量的值大于0,表示资源可用,进程可以继续执行并将信号量的值减少1。如果信号量的值为0,表示资源已经被其他进程占用,此时进程会被阻塞,等待资源释放。 V操作(Signal操作)用于释放资源。当进程使用完一个共享资源后,它会对信号量进行V操作。V操作会将信号量的值加1,表示资源已经被释放。如果有其他进程在等待该资源,那么其中一个进程将被唤醒继续执行。 通过信号量PV操作,可以实现进程的互斥和同步。当多个进程同时访问一个共享资源时,信号量可以控制对资源的访问顺序,避免数据的竞争和冲突。例如,在多个进程并发读写文件时,可以使用信号量来保证同一时间只有一个进程对文件进行读写操作。 在实际应用中,操作系统信号量用于解决进程之间的竞争和资源分配的问题。通过合理的使用信号量,可以实现进程的并发执行和协同工作。在编程中,我们可以使用各种编程语言提供的信号量库函数或系统调用来实现信号量的操作,如C语言中的sem_init()、sem_wait()、sem_post()等函数。 总之,信号量PV类题目是计算机操作系统中常见的题型,需要理解PV操作的含义和作用,以及如何使用信号量来解决进程之间的同步和通信问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值