APUE---chap10信号---10.1~10.3

10.1 引言

  • 信号是软中断
  • 同步:按照顺序处理事情,单线程思想。

同步的例子:

比如去餐厅吃饭,来一个客人,点一个菜,厨师做好了,在让下一个个人点菜。优缺点“速度慢,但不会出现错误。

  • 异步:事情依次分配给不同线程,多线程同时处理。不论是否处理完,仍然接收其他的任务。

异步的实际例子:

比如去餐厅吃饭,来一个客人,点一个菜,下一个客人来了,继续点菜。不管厨师做好没有,这样可提高效率,让厨师一直在做菜。

异步事件的处理:1.查询法:事件发生频率高 2.通知法:事件发生事件频率低。

  • 并发:

信号和线程

10.2 信号概念:

在头文件<signal.h>里面有系统定义好的一些信号类型,比如下面这些:

当程序在运行时,系统发出某个信号后,正在运行的程序收到此信号的响应动作有三种:

(1)忽略信号

(2)捕捉信号,执行用户设定的函数

(3)执行系统的默认操作 

注:信号的具体含义及默认操作等,可看书具体理解,平时用掌握常见的操作即可。

10.3 函数 signal

在终端输入:man signal 

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

参数: signum 就是10.2中截图中所列的那些参数

         handler就是一个函数指针,代表当这个信号来了,执行handler函数

书上有如下例子:

// g++ main.cpp

#include <err.h>
#include <signal.h>
#include <unistd.h>
#include "stdio.h"
static void sig_usr(int); /* one handler for both signals */

int main(void) {
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR1");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR2");
    for (;;)
        pause();  // wait for signal
}

static void sig_usr(int signo) /* argument is signal number */
{
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGUSR2)
        printf("received SIGUSR2\n");
    else
        printf("received signal %d\n", signo);
}
#执行程序
lbw:~/lbw/gitNote$ ./a.out 
received SIGUSR1
received SIGUSR2

#查找PID
lbw:~/lbw/gitNote$ ps -a
2727261 pts/1    00:00:00 a.out

#向程序发送信号SIGUSR1和SIGUSR2
lbw:~/lbw/gitNote$ kill -10 2727261
lbw:~/lbw/gitNote$ kill -12 2727261
  • 使用SIG_IGN来忽略对信号的处理:
signal(SIGUSR1, SIG_IGN);  //程序收到SIGUSR1信号无任何响应动作

ctrl + c === SIGINT   //终端中断符

ctrl + z === SIGQUIT

  • 信号会打断阻塞的系统调用; 而被中断的调用会将errno置为 EINTR,所以可检查错误,有如下的例子来确保被信号打断的系统调能正常调用。
// 信号会打断阻塞的系统调用:为了防止出现调用open()---》signal过来了打断open()--->需要在open 失败检查加上错误检查
// EINTR代表被打断的系统调用中断
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
    int sfd;
    do {
        sfd = open(argv[1], O_RDONLY);
        if (sfd < 0) {
            // error check:
            if (errno != EINTR) {
                perror("open()");
                exit(1);
            }
        }
    } while (sfd < 0);

    close(sfd);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值