• PIPE、SIGNAL(day11)


    一、管道
    管道分为两种:   无名管道    有名管道
    无名管道用于具有亲缘关系的进程间通讯。无名管道是单工的。
    有内核管理的一块内存空间。
    使用管道,系统提供了pipe(2)
    #include <unistd.h>
    int pipe(int pipefd[2]);
    功能:创建管道
    参数:
    pipefd[2]:用于返回管道的两端。pipefd[0]指向管道的读端。
    pipefd[1]指向管道的写端。
    
    返回值:
    0  成功。
    -1  错误  errno被设置
    
    使用管道实现两个进程间的通讯。
    步骤:
    (一)、父进程创建管道
    (二)、父进程创建子进程(子进程继承了父进程的文件描述符)
    (三)、父进程负责的工作
    1、关闭读端
    2、通过管道的写端文件描述符,写数据到管道空间。
    3、阻塞等待子进程的结束。子进程结束的时候,收尸
    
    (四)、子进程负责的工作
    1、关闭写端
    2、从管道中读取数据
    3、将读取到的数据,输出到显示器
    4、结束进程。
    
    代码的实现    pipe.c
    
    有名管道
    有名管道其实是一个文件,这个文件只能用于两个进程间通讯的桥梁。不存储任何数据内容。
    如何创建一个有名管道的文件。使用mkfifo(3)
    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
    功能:创建一个有名管道文件
    参数:
    pathname:指定了有名管道文件的名字
    mode:指定了管道文件的权限   mode & ~umask
    返回值:
    0  成功
    -1  错误  errno被设置
    
    编码实现管道文件的创建。  文件名字由命令行第一个参数传入,权限为0664.
    代码参见  mkfifo.c
    编写代码向有名管道写数据。代码参见PA.c
    编写代码实现从有名管道读取数据  代码参见PB.c
    
    进程结束了。  尝试将管道添加到psh中
    
    二、信号的基础
    什么是信号?
    信号就是软中断。
    软中断就是软件模拟的中断机制。
    中断又是什么?
    正常的执行流程、中断处理程序
    
    正常的执行流程、信号处理程序是两条执行路线,但是属于同一个进程。
    系统为我们提供了哪些信号呢?
    kill -l
    
    信号有名字和编号。
    
    信号的产生到消失的过程。
    信号的产生、信号阻塞、信号递达进程、信号处理
    信号的未决状态   就是信号产生了,但是信号还没有被进程处理,这期间,信号的状态为未决状态。
    
    进程可以设置对信号的阻塞。
    
    三、改变信号的处理函数
    进程对信号的处理有默认动作。默认处理是终止进程。
    除此之外,还有两种  忽略信号    用户自定义
    进程从父进程继承信号处理函数。
    SIG_DFL   默认    
    SIG_IGN   忽略
    doit     用户自定义的信号处理函数
    
    系统提供了signal(2) 用来改变信号的处理函数
    #include <signal.h>
    typedef void (*sighandler_t)(int);
    sighandler_t  signal(int signum, sighandler_t handler);
    功能:
    参数:
    signum:指定了信号的编号
    handler:指定了signum信号的处理函数
     SIG_IGN, SIG_DFL, 用户自定义函数
    返回值:
    SIG_ERR   错误
    返回的是旧的信号处理函数的地址
    
    typedef void (*sighandler_t)(int);
    
    举例说明   编码实现进程忽略2号信号   代码参见signal2.c
    编码实现进程对2号信号的处理采用用户自定义的函数。
    代码参见   signal_2u.c
    
    
    四、信号的产生
    信号产生的三种形式:
    1、硬件产生信号    ctrl+c    ctrl+
    2、使用命令为进程发送信号    kill -信号编号   pid
    3、使用库函数或者系统调用为进程发送信号
    kill(2)
    #include <sys/types.h>
    #include <signal.h>
    int kill(pid_t pid, int sig);
    功能:给一个进程发送信号
    参数:
    pid:指定了接收信号的进程的pid
    sig:指定了具体的信号
    返回值:
    0  成功
    -1  错误  errno被设置
    
    举例说明   编写代码实现kill命令的功能。代码参见pkill.c
    
    raise(3)
    #include <signal.h>
    int raise(int sig);
    功能:发送信号给当前进程
    参数:
    sig:指定信号的编号
    返回值:
    0  成功
    非0   错误
    
    举例说明,使用raise给当前进程发送信号   代码参见 raise.c
    
    alarm(2) 产生SIGALRM信号
    #include <unistd.h>
    unsigned int alarm(unsigned int seconds);
    功能:产生SIGALRM信号,将这个信号发送给当前进程
    参数:
    seconds:指定了闹钟的时间。如果这个参数为0.取消闹钟。
    
    返回值:
    返回剩余的没执行的时间值。
    
    举例说明   编写代码实现每一秒钟输出的数字。代码参见  count.c
    
    五、信号阻塞和未决信号
    
    信号集类型 sigset_t
    
    系统对sigset_t 类型进行了封装
    
    #include <signal.h>
    int sigemptyset(sigset_t *set);
    功能:初始化信号集为空,不包含任何信号
    参数:
    set:指定要初始化的信号集
    返回值:
    0  成功
    -1 错误
    
    int sigfillset(sigset_t *set);
    功能:初始化信号集为满,包含所有的信号
    参数:
    set:指定要初始化的信号集
    返回值:
    0  成功
    -1 错误
    
    int sigaddset(sigset_t *set,int signum);
    功能:添加指定的信号到信号集
    参数:
    set:指定信号集
    signum:指定信号
    返回值:
    0  成功
    -1 错误
    
    int sigdelset(sigset_t *set,int signum);
    功能:从指定信号集删除指定的信号
    参数:
    set:指定信号集
    signum:指定信号
    返回值:
    0  成功
    -1 错误
    
    int sigismember(const sigset_t *set, int signum);
    功能:测试信号是否是集合的一员
    参数:
    set:指定信号集
    signum:指定信号
    返回值:
    -1  错误
    10 不是
    
    通过sigprocmask(2)设置信号集为进程的屏蔽字。
    #include <signal.h>
    int sigprocmask(int how,const sigset_t *set,
             sigset_t *oldset);
    功能:检查或者改变阻塞信号
    参数:
    how:
    SIG_BLOCK:原来的set和set的并集
    SIG_UNBLOCK:将set集合中的信号从当前进程的set中移除。
    SIG_SETMASK:将set设置为当前进程的信号屏蔽字
    
    set:新的信号屏蔽字。
    oldset:保存进程原来的信号屏蔽字。如果为NULL,不保存。
    返回值:
    成功  0
    -1  错误
    
    举例说明   编写代码实现对2号信号的阻塞。
    代码参见  blocked2.c
    
    多次发送2号信号,进程对2号信号阻塞,在解除阻塞的时候,信号处理函数只执行一次,造成了信号的丢失。这样的信号叫不可靠信号。 1~31
    
    34~64   称为可靠信号,不会有信号丢失。
    
    检测进程的未决信号
    sigpending(2)
    #include <signal.h>
    int sigpending(sigset_t *set);
    功能:检测未决信号
    参数:
    set:未决信号掩码被存放在这个集合中
    返回值:
    成功  0
    错误 -1
    
    举例说明   检测进程的未决信号集
    代码参见  pending.c
    
    
    总结:
    一  管道 (无名管道   有名管道)
    二、信号基础
    三、信号的处理
    signal(2)
    四、信号的产生
    五、信号阻塞和未决信号
  • 相关阅读:
    8.图形软件开发
    7.GDI绘图技术
    15.MFC网络通信
    JavaWeb:基于MVC设计模式的一个小案例(一)
    在虚拟机里连接PLC S7-200
    mark-又重新回到博客园
    早起的奇迹
    STM32-cJSON库的打包和解析
    Copley-STM32串口+CANopen实现双电机力矩同步
    DataStructure-链表实现指数非递减一元多项式的求和
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7732616.html
Copyright © 2020-2023  润新知