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

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() 设置信号处理方式。

  • 消息队列

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

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

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

    • 提供不同主机上的进程之间进行通信的机制
相关推荐
老鼠只爱大米几秒前
LeetCode经典算法面试题 #108:将有序数组转换为二叉搜索树(递归分治、迭代法等多种实现方案详解)
算法·leetcode·二叉树·二叉搜索树·平衡树·分治法
独角鲸网络安全实验室11 分钟前
本地信任成“致命漏洞”:数千Clawdbot Agent公网裸奔,供应链与内网安全告急
网络·网关·安全·php·漏洞·clawdbot·信任机制漏洞
郭涤生12 分钟前
C++的函数是否可以做到完全覆盖Linux和windows的跨平台
linux·c++·windows
ai_xiaogui14 分钟前
Tailscale实现家庭与公司网络双向通信教程:子网路由配置详解
网络·tailscale·双向通信·子网路由配置详解·tailscale双向互访
怪兽源码23 分钟前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite30 分钟前
Redis之配置只读账号
java·redis·bootstrap
独自破碎E30 分钟前
【前缀和+哈希】LCR_011_连续数组
算法·哈希算法
梦里小白龙35 分钟前
java 通过Minio上传文件
java·开发语言
人道领域36 分钟前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
一条大祥脚37 分钟前
26.1.26 扫描线+数论|因子反演+子序列计数|树套树优化最短路
数据结构·算法