Linux:信号

  1. 信号的基本介绍
    每个信号都有一个名字。这些名字都以三个字符 S I G开头。
    很多条件可以产生一个信号
    当用户按某些终端键时,产生信号。
    硬件异常产生信号:除数为0、无效的存储访问等等。
  2. kill -l 看系统的信号
  3. 响应信号
    默认、
    忽略、SIGKILL SIGSTOP不能忽略
    捕获并处理 SIGKILL SIGSTOP不能捕获并处理

信号处理函数

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

SIGINT

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void handler(int s){ 
    printf("你弄不死我\n");
}

int main( void) {
    signal(SIGINT, handler);

    for ( ; ; ) { 
        printf(".");
        fflush(stdout);
        sleep(1);
    }   
}
------------------------------------------------
[root@localhost ~]# ./a.out
.....^C你弄不死我
....^C你弄不死我
.....^\退出(吐核)

信号的分类

  • 可靠信号
  • 不可靠信号
  • 非实时信号
  • 实时信号SIGRH

kill
int kill(pid_t pid, int signo) ;
kill的p i d参数不同的情况:

  • pid > 0 将信号发送给进程ID为pid的进程。
  • pid == 0 将信号发送给其进程组ID等于发送进程的进程组ID,而且发送进程有许可权向其发送信号的所有进程。
  • pid < 0 将信号发送给其进程组ID等于pid绝对值,而且发送进程有许可权向其发送信号
    的所有进程。如上所述一样,“所有进程”并不包括系统进程集中的进程。
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void handler(int s) {
    printf("recv %d\n", s); 
    exit(0);
}

int main( void ) { 
    signal(SIGUSR1, handler);

    pid_t pid = fork();
    if ( pid == 0 ) { 
        sleep(3);
        kill(getppid(), SIGUSR1);

    } else {
        for ( ; ; ) { 
            printf(".");
            fflush(stdout);
        }   
    }   
}

打印彩色9*9乘法表

#include <stdio.h>
#include <stdlib.h>

int main( void ) { 
    int i, j;
    for (i=1; i<=9; i++) {
        for (j=1; j<=i; j++) {
            printf("\033[3%dm%dX%d=%-3d ", (i%8), j, i, i*j);
        }   
        printf("\n");
    }   
    printf("\033[0m");
}

信号在内核中的表示

信号从产生到执行信号处理函数,把执行信号处理函数的动作称为抵达。
从产生到抵达之间的状态称为信号未决。

sigset_t:信号集
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
SIG_BLOCK mask |= *set
SIG_UNBLOCK mask &= ~set
SIG_SETMASK mask *= *set

模拟弹出U盘

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void handler(int s) {
    printf("recv %d\n", s); 
}
int main( void ) { 
    signal(SIGINT, handler);

    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sigprocmask(SIG_BLOCK, &set, NULL);
    int i;
    for (i=0; i<5; i++) {
        printf("开始拷贝%d集视频\n", i+1);
        sleep(3);
        printf("第%d集视频拷贝完毕\n", i+1);
    }   

    // 解除信号屏蔽
    sigprocmask(SIG_UNBLOCK, &set, NULL);

    for ( ; ; ) {
        printf(".");
        sleep(1);
        fflush(stdout);
    }
}
-------------------------------------------
/*[root@localhost ~]# ./a.out
开始拷贝1集视频
^C第1集视频拷贝完毕
开始拷贝2集视频
^C^C^C^C^C^C^C第2集视频拷贝完毕
开始拷贝3集视频
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C第3集视频拷贝完毕
开始拷贝4集视频
^C^C^C^C第4集视频拷贝完毕
开始拷贝5集视频
第5集视频拷贝完毕
recv 2
..^C.recv 2
..^C.recv 2
..^\退出(吐核)
*/

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void handler(int s) {
    printf("recv %d\n", s); 
}

int main(void) {
    struct sigaction act;
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGINT, &act, NULL);

    for ( ; ; ) { 
        printf(".");
        fflush(stdout);
        sleep(1);
    }   
}
----------------------------------------------
/*[root@localhost ~]# ./a.out
.......^Crecv 2
....^Crecv 2
..^\退出(吐核)
*/

IPC进程间通信:互斥、同步
进程间通信的目的:数据传递、资源共享、通知事件
进程间通信方式:管道、syatem V 进程间通信 IPC、消息队列、共享内存、信号量
POSIX 进程间通信:信号量、信号、互斥量、读写锁、自旋锁、条件变量
死锁的必要条件:互斥性、请求并保持、不可剥夺、环路等待
银行家算法:
1.客户的最大资金需求,不超过银行家现有的资金,接纳该客户。
2.客户可以分期贷款,但是贷款的总额不能超过最大资金需求量。
3.当银行家现有的资金量不能满足客户需求,总能在有限的时间内贷款给客户。
4.客户拿到全部资金后,总能够在有限的时间内归还。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值