无名管道、有名管道、信号、信号处理

1. 进程间通信(IPC)

进程间通信(IPC)是指在不同进程之间交换数据或信息的机制。常见的 IPC 方法包括:

1.1 管道(Pipe)
  • 无名管道(Anonymous Pipe)

    • 只能用于具有亲缘关系的进程间通信(如父子进程)。

    • 使用 pipe() 系统调用创建。

    • 特点:

      • 读操作:如果管道中有数据,则直接读取;如果没有数据,会阻塞等待。

      • 写操作:如果管道中有读端且未满,则直接写入;如果管道已满,会阻塞等待。

      • 如果管道中没有读端,写入数据会导致管道破裂(SIGPIPE 信号)。

  • 有名管道(Named Pipe/FIFO)

    • 可以用于任意两个进程之间的通信。

    • 使用 mkfifo() 系统调用创建。

    • 特点:

      • 必须读写两端同时打开,才能继续执行;否则会阻塞等待。
1.2 信号(Signal)
  • 定义

    • 提供一种内核层与用户层之间的通知机制。

    • 信号是一种软件中断,用于通知进程某些事件的发生。

  • 信号类型

    • SIGINT(2):中断信号(如 Ctrl+C)。

    • SIGQUIT(3):退出信号(如 Ctrl+\)。

    • SIGSEGV(11):段错误。

    • SIGPIPE(13):管道破裂。

    • SIGALRM(14):定时信号。

    • SIGCHLD(17):子进程结束。

    • SIGSTOP(19):停止进程。

    • SIGTSTP(20):挂起进程(如 Ctrl+Z)。

    • SIGIO(29):异步 I/O 信号。

  • 对信号的处理方式

    1. 忽略:信号来了,不处理该信号。

    2. 缺省:信号来了,按照默认的方式处理信号。

    3. 捕捉:信号来了,按照指定的方式处理信号。

    • 注意:SIGKILL(9)和 SIGSTOP(19)不能被忽略或捕捉。
  • 函数接口

    复制代码
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler);
    • 功能:修改信号的处理方式。

    • 参数:

      • signum:信号编号。

      • handler:信号处理方式(SIG_IGN 忽略,SIG_DFL 缺省)。

    • 返回值:

      • 成功返回之前的信号处理函数。

      • 失败返回 SIG_ERR

1.3 消息队列(Message Queue)
  • 提供一种在进程间传递消息的机制。

  • 消息队列允许一个或多个进程向队列中写入消息,同时允许一个或多个进程读取这些消息。

1.4 共享内存(Shared Memory)
  • 允许多个进程共享同一块内存区域。

  • 提供高效的进程间通信,但需要同步机制(如互斥锁)来避免数据竞争。

1.5 信号量(Semaphore)
  • 提供一种同步机制,用于控制对共享资源的访问。

  • 函数接口:

    复制代码
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    int sem_destroy(sem_t *sem);
    int sem_wait(sem_t *sem);
    int sem_post(sem_t *sem);
    • sem_init:初始化信号量。

    • sem_destroy:销毁信号量。

    • sem_wait:申请信号量资源(资源数 - 1)。

    • sem_post:释放信号量资源(资源数 + 1)。

1.6 套接字(Socket)
  • 提供一种在不同主机上的进程之间进行通信的机制。

  • 支持多种协议(如 TCP/IP、UDP/IP)。


2. 管道的详细说明

2.1 无名管道
  • 创建

    复制代码
    int pipe(int pipefd[2]);
    • 功能:创建操作管道的两个文件描述符。

    • 参数:

      • pipefd[0]:读文件描述符。

      • pipefd[1]:写文件描述符。

    • 返回值:

      • 成功返回 0。

      • 失败返回 -1。

2.2 有名管道
  • 创建

    复制代码
    int mkfifo(const char *pathname, mode_t mode);
    • 功能:创建管道文件。

    • 参数:

      • pathname:管道文件名。

      • mode:权限。

    • 返回值:

      • 成功返回 0。

      • 失败返回 -1。


3. 信号的详细说明

3.1 信号处理
  • 信号列表

    • 使用 kill -l 命令查看所有信号。

    • 示例:

      复制代码
      1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
      6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
      11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
  • 信号处理方式

    • 忽略SIG_IGN

    • 缺省SIG_DFL

    • 捕捉:自定义处理函数。

  • 示例代码

    复制代码
    #include <stdio.h>
    #include <signal.h>
    
    void handle_sigint(int sig) {
        printf("SIGINT signal received\n");
    }
    
    void handle_sigquit(int sig) {
        printf("SIGQUIT signal received\n");
    }
    
    int main() {
        signal(SIGINT, handle_sigint);  // 捕捉 SIGINT
        signal(SIGQUIT, handle_sigquit);  // 捕捉 SIGQUIT
    
        printf("Press Ctrl+C or Ctrl+\\ to test signals\n");
        while (1) {
            // 等待信号
        }
    
        return 0;
    }
3.2 定时信号
  • alarm()

    复制代码
    unsigned int alarm(unsigned int seconds);
    • 功能:定时 seconds 秒后给当前进程发送 SIGALRM 信号。

    • 参数:

      • seconds:秒数。
    • 返回值:

      • 成功返回之前定时剩余的秒数。

      • 如果之前没有定时返回 0。

3.3 发送信号
  • kill()

    复制代码
    int kill(pid_t pid, int sig);
    • 功能:向 pid 对应的进程发送 sig 信号。

    • 参数:

      • pid:目标进程的 PID。

      • sig:信号编号。

    • 返回值:

      • 成功返回 0。

      • 失败返回 -1。


4. 总结

  • 管道

    • 无名管道:用于具有亲缘关系的进程间通信。

    • 有名管道:用于任意两个进程之间的通信。

  • 信号

    • 提供内核层与用户层之间的通知机制。

    • 可以通过 signal() 设置信号处理方式。

  • 消息队列

    • 提供进程间传递消息的机制。
  • 共享内存

    • 提供高效的进程间通信,但需要同步机制。
  • 信号量

    • 提供同步机制,用于控制对共享资源的访问。
  • 套接字

    • 提供不同主机上的进程之间进行通信的机制
相关推荐
时间会给答案scidag2 分钟前
maven高级
java·服务器·前端
Leo1871 小时前
parallelStream线程问题及解决方案
java·spring boot
阿黄学技术1 小时前
Redis场景问题2:缓存击穿
java·数据库·redis·缓存
Tryagein2 小时前
【数据结构】并查集
数据结构·算法
Joe_Wang52 小时前
[数据结构]并查集(系统整理版)
数据结构·c++·算法·leetcode·并查集
写代码的橘子n2 小时前
SpringBoot项目中,controller 、 entity、mapper和service包的介绍
java·tomcat
你住过的屋檐3 小时前
【RabbitMQ】Linux上安装RabbitMQ详细步骤
linux·rabbitmq·ruby
王伯爵3 小时前
5G核心网(5GC)中PCC(Policy and Charging Control,策略与计费控制)
服务器·网络·5g
Tryagein4 小时前
【数据结构】树与森林
数据结构
敲键盘的小夜猫4 小时前
Redisson延迟队列实战:分布式系统中的“时间管理者“
java·redis·分布式