华清远见嵌入式学习day17——进程间通信

【1】进程间的通信
    传统的进程间通信方式
    无名管道、有名管道、信号
    
    System V IPC对象
    共享内存、消息队列、信号灯集

    
    BSD 
    套接字
【2】无名管道
    1.只能用于具有亲缘关系的进程之间通信
    2.半双工的通信模式,具有固定的读端和写端
    3.管道可以看成是一种特殊的文件,对于它的读写可以用文件IO,read、write
    
    #include <unistd.h>

    int pipe(int pipefd[2]);
    功能:创建一个无名管道
    参数:pipefd[]  是一个数组,用来存放两个文件描述符
          pipefd[0]   读端
          pipefd[1]   写端
    返回值:成功返回0   失败返回-1
    
【3】管道的读写特性
    读特性:
    1.写端存在
        管道中有数据,读数据
        管道中没有数据,读阻塞
    2.写端不存在
        管道中没有数据,读不到内容
        管道中有数据,读相应的数据
    写特性
    1.读端存在
        可以向管道中写,写满了写会阻塞
    2.读端不存在
        向管道中写会造成管道断裂,进程直接结束

练习:测试当前系统无名管道的大小?    (65536字节)    
【特别提醒】:管道不能用lseek进行偏移        

练习:利用管道进行进程间通信,父进程当写端,子进程当读端,实现输入和打印
    1.父子进程?
    2.无名管道、父子进程怎么就都知道了?
    3.对于无用的文件描述符记得关闭
        
【4】有名管道
    管道可以在文件系统中看到,可以用于两个互不相关的进程通信
    1.mkfifo命令
        mkfifo 管道名
    2.mkfifo函数
       #include <sys/types.h>
       #include <sys/stat.h>

       int mkfifo(const char *pathname, mode_t mode);
       功能:创建有名管道
       参数:pathname    管道的名字
             mode        指定有名管道的权限
       返回值:成功返回0   失败返回-1
【5】有名管道的特点
    1.一台机器上的任意两个进程间通信
    2.全双工的模式,读写都是一端
    3.有名管道在文件系统可见,可以用文件IO来操作
    4.有名管道也不支持lseek
    5.当一个进程使用open函数O_RDONLY或O_WRONLY打开时,open函数会阻塞,直到另一个进程以对应的方式打开

练习:利用有名管道,实现两个不同进程通信,拷贝文件
    1.进程1:从源文件中读,写到管道中
    2.进程2:从管道中读,写到目标文件中
    
【6】信号
    信号是在软件层次上对中断机制的一种模拟,它是进程间唯一的一种异步通信方式
    信号由内核产生,递交给用户空间来处理

    
    kill -l
    
    SIGKILL  不能阻塞、处理、忽略
    SIGSTOP  不能阻塞、处理、忽略
    

    用户进程对信号的响应方式
    1.忽略信号:对信号不做任何处理,但是有两个不能忽略SIGKILL和SIGSTOP
    2.执行缺省操作:执行默认操作
    3.捕捉信号:当信号发生时,执行我们自己规定的事情
    

    kill 信号  pid
    kill -9 pid
    默认发送15信号

【7】信号相关函数
       信号注册函数:
       #include <signal.h>

       typedef void (*sighandler_t)(int);

       sighandler_t signal(int signum, sighandler_t handler);
       功能:注册一个信号(回调函数)
       参数:signum   信号
             handler  函数指针变量
                    1.自己定义一个函数
                    2.SIG_IGN  忽略
                    3.SIG_DFL  缺省操作

       返回值:成功返回函数指针,失败返回SIG_ERR
       
        理解过程:
        int *p;--》void (*)(int)  sighandler_t
        typedef (int *) p;  p是一个数据类型--》typedef void (*)(int)  sighandler_t
        p q;--》sighandler_t  handler;
        handler--》void fun(int )

       发送信号:
       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);
       功能:给进程发送信号
       参数:pid  进程的pid
             sig  要发送的信号
       返回值:成功返回0   失败返回-1
       
       #include <signal.h>

       int raise(int sig);
       功能:给自己发送信号
       参数:sig   要发送的信号
       返回值:成功返回0,失败非0
       
       定时器函数:
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);
       功能:给进程设定时间,一个进程只能设定一个时间
       参数:seconds   设定的秒数   0代表取消闹钟
       返回值:成功:如果调用alarm()前,进程已经设定过闹钟,则返回上一个闹钟的剩余时间
               否则返回0;
    

    
    

猜你喜欢

转载自blog.csdn.net/UemTuBXuR/article/details/89053612