进程间通信 管道 信号

18 篇文章 0 订阅

【1】进程间通信方式

  1. 基本进程通信方式
    无名管道 、有名管道、信号

  2. system V IPC对象
    共享内存、信号灯集、消息队列

  3. BSD
    套接字

【2】无名管道

  1. 特点:

    1. 只能用于具有亲缘关系的进程之间的通信

    2. 无名管道是单工管道,半双工的通信模式,具有固定的读端和写端

    3. 管道可以看成是一种特殊的文件,对于它的读写可以使用文
      件IO如read、write函数。

    4. 管道是基于文件描述符的通信方式。当一个管道建立时,
      它会创建两个文件描述符fd[0]fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

    5. 无名管道的操作属于一次性操作,如果对无名管道进行读操作,
      数据会被全部读走

    6. 无名管道的大小是固定的,管道一旦满,写操作就会导致进程阻塞,
      管道的大小是64K。只有读出大于等于4K之后,写操作解除阻塞。

    7. 当管道中无数据时,执行读操作,读操作阻塞。

    8. 无名管道不保证操作的原子性,如果当前管道,
      满足读写条件,读写可同时进行。

    9. 向无名管道中写去数据,将读端关闭,管道破裂,
      进程收到信号(SIGPIPE),默认这个信号会将进程杀死 。

    10. 当管道中有数据,将写端关闭,读操作可以执行,
      之后数据读完,可以继续读取(非阻塞),直接返回0。

    11. 无需open,但需手动close

    12. 不支持如lseek() 操作。队列形式,先进先出,属于一次性操作。

  2. 函数
    int pipe(int fd[2])
    功能:创建无名管道
    参数:文件描述符 fd[0]:读端 fd[1]:写端
    返回值:成功 0
    失败 -1

  3. 注意事项:

    1. 当管道中无数据时,读操作会阻塞
    2. 管道中装满数据写阻塞,一旦有4k空间,写继续
    3. 只有在管道的读端存在时,向管道中写入数据才有意义。否则,
      会导致管道破裂,向管道中写入数据的进程将收到内核传来的SIGPIPE信号
      (通常Broken pipe错误)。

【3】有名管道:

  1. 特点:

    1. 有名管道可以使互不相关的两个进程互相通信。
    2. 有名管道可以通过路径名来指出,并且在文件系统中可见,
      但内容存放在内存中。不存到磁盘上。
    3. 进程通过文件IO来操作有名管道,需要用open打开
    4. 有名管道以队列的方式先进先出
    5. 一次性操作,不支持lseek()
  2. 相关函数:
    通过命令创建 mkfifo my_fifo
    $ mkfifo filename -m mode
    mkfifo myfifo -m 0666(创建一个命名管道myfifo,其权限为0666)
    创建管道文件成功后,只是对应在磁盘中有这个文件了,
    并没有对应的内存,只有在一个进程用open打开这个文件后,
    这个管道缓冲区(数组)才会开辟存在。close关闭后其缓冲区释放不存在。

    1. int mkfifo(const char *filename,mode_t mode);
      功能:创健有名管道
      参数:filename:有名管道文件名
      mode:权限
      返回值:成功:0
      失败:-1,并设置errno号
      注意对错误的处理方式:
      如果错误是file exist时,注意加判断,如:
      if(errno == EEXIST)
  3. 注意:
    O_WRONLY打开管道,写阻塞
    O_RDONLY打开管道,读阻塞
    O_RDWR打开管道,管道中没有内容,读阻塞

#include <stdlib.h>
int system(const char *command);
功能:调用可执行命令,实现命令功能。
system("rm fifo");删除管道文件

【4】信号:

  1. 概念:

    1. 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
    2. 信号可以直接进行用户空间进程和内核进程之间的交互,内核
      进程也可以利用它来通知用户空间进程发生了哪些系统事件。
    3. 如果该进程当前并未处于执行态,则该信号就由内核保存起来,
      直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,
      则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
  2. 用户进程对信号的响应方式:

    1. 忽略信号:对信号不做任何处理,但是有两个信号不能忽略:
      SIGKILLSIGSTOP
    2. 捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。
    3. 执行缺省操作:Linux对每种信号都规定了默认操作
  3. 信号:kill -l
    SIGINTctrl+c 终止信号
    SIGQUITctrl+\ 终止信号
    SIGTSTP:ctrl+z 暂停信号
    SIGALRM:闹钟信号 收到此信号后定时结束,结束进程
    SIGCHLD:子进程状态改变,父进程收到信号

SIGKILL:杀死信号
SIGSTOP:停止信号

SIGUSR1、SIGUSR2-->未定义默认功能的信号
  1. 相关函数:

    1. int kill(pid_t pid, int sig);
      功能:信号发送
      参数:pid:指定进程
      sig:要发送的信号
      返回值:成功 0
      失败 -1

    2. int raise(int sig);
      功能:进程向自己发送信号
      参数:sig:信号
      返回值:成功 0
      失败 -1

    3. unsigned int alarm(unsigned int seconds)
      功能:在进程中设置一个定时器
      参数:seconds:定时时间,单位为秒
      返回值:如果调用此alarm()前,进程中已经设置了闹钟时间,则
      返回上一个闹钟时间的剩余时间,否则返回0。
      注意:一个进程只能有一个闹钟时间。如果在调用alarm时
      已设置过闹钟时间,则之前的闹钟时间被新值所代替

    4. int pause(void);
      功能:用于将调用进程挂起直到收到信号为止。

    5. void (*signal(int signum, void (*handler)(int)))(int);
      或者:

    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler)
    功能:信号处理函数(注册信号)
    参数:signum:要处理的信号
    handlerSIG_IGN:忽略该信号。
    SIG_DFL:采用系统默认方式处理信号。
    自定义的信号处理函数指针
    返回值:成功:设置之前的信号处理方式
    失败:SIG_ERR

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值