当前位置: 首页 > article >正文

Linux应用软件编程(多任务:进程间通信)

一.进程间通信
          同一主机下:
        (1)无名管道:pipe   (2)有名管道:fifo    (3)信号:异步通知机制
       (4)共享内存:效率最高   (5)消息队列    (6)信号量集(信号灯):进程间同步
          不同主机下: 网络套接字 

二.管道(用于同步通信)
     无名管道:用于同一主机下,具有亲缘关系的父子进程间通信。 
     有名管道:用于同一主机下,任意进程间通信。

 (1)无名管道

1. 创建一个无名管道并打开
int pipe(int pipefd[2]);
功能:
参数:
        pipefd:
                    pipefd[0] : 管道的读端
                    pipefd[1] : 管道的写端
返回值: 
          成功:0;
          失败:-1
2. 读管道:read        3. 写管道: write           4. 关闭管道: close

5.void *memset(void *s, int c, size_t n);   将内存清成指定字节

无名管道的特性:

1. 默认64K大小

2. 管道存储数据时,按照FIFO(队列)的方式存储。

3. 写阻塞:管道读写端都存在时,向管道中写入数据,当管道满时,发生写阻塞。
    读阻塞:管道读写端都存在时,从管道中读数据,如果管道中有数据,read返回实际读到的字节数;(如果管道中无数据,read发生读阻塞)

    读到0:管道的写端关闭,只保留读端,从管道读数据,若有数据,则读到数据,
                  若无数据,则read返回0,不阻塞。
    管道破裂:管道的读端关闭,只保留写端,向管道中写入数据,发生管道破裂(异常)

(2)有名管道

   

1. 创建管道文件
     int mkfifo(const char *pathname, mode_t mode);    
2. 打开管道文件 : open  (读端和写端必须同时打开)
3. 读写管道文件 : write/read
4. 关闭管道文件 :close
5. 删除管道文件 : remove

三.信号(进程间的异步通知(通信)机制    软中断)

 1. 信号类型(用kill  -l查看 )

   常见信号类型:

     2) SIGINT:ctrl + c 
         让一个进程被打断
    3) SIGQUIT:ctrl + \
        让一个进程结束
    9) SIGKILL:
        强制让一个进程结束
    11)SIGSEGV:
        让一个进程结束(段错误)
    13)SIGPIPE:
        让一个进程结束(管道破裂)
    14)SIGALRM:
        让一个进程结束(定时时间到达)
    17)SIGCHLD:
        子进程结束时发送给父进程
    18)SIGCONT:
        让停止态的进程继续执行
    19)SIGSTOP:
        让运行态的进程进入停止态(暂停)强制停止
    20)SIGTSTP:
        ctrl + z   让进程进入暂停态,后台进程
        来自终端的停止信号

      用户自定义信号 :SIGUSR1     SIGUSR2

     管理员信号:无法被捕获和忽略( 9  SIGKILL    19  SIGSTOP )

2. 接收信号

        1. 忽略:不处理
        2 .捕获:按照用户自定义方式处理
        3. 缺省:按照信号默认方式处(若不注册)

        (1)注册信号处理函数             
                  typedef void (*sighandler_t)(int);

                  sighandler_t signal(int signum, sighandler_t handler);
                  功能:信号的接收方,注册一个信号处理函数
                  参数:
                             signum:注册的信号的编号
                             handler:
                                           SIG_IGN :   以忽略方式处理
                                           SIG_DFL:    以缺省方式处理
                                           函数的地址:以捕获方式处理                     
                   返回值:
                                失败:SIG_ERR
3. 发送信号:    
      int kill(pid_t pid, int sig);
      功能:给指定进程发送信号
      参数:
               pid:进程pid号
               sig:发送的信号编号

       int pause(void);
       功能:挂起当前进程    (S:可中断睡眠状态)

        可以通过发送信号的方式,唤醒pause挂起的进程,信号必须被捕获。

              unsigned int alarm(unsigned int seconds);
      功能:
          间隔seconds秒后给调用进程发送一个SIGALRM信号

四.共享内存

  内存映射:避免数据的反复读写拷贝,提高了效率。

0.获取一个IPC的key值

   key_t ftok(const char *pathname, int proj_id);

功能:获取IPC的key值

参数:

       pathname:路径                    proj_id:项目ID

返回值:成功:key                      失败:-1

1.创建共享内存

int shmget(key_t key, size_t size, int shmflg);

功能:根据key值创建共享内存

参数:

         key:IPC的key值

        size:共享内存大小(向上取整到页大小的整数倍)(PAGE-SIZE  4096)

        shmflag:对对象内存的操作

                         IPC_CREAT | 0664  (创建)

返回值:成功:共享内存的ID      失败:-1

2.建立共享内存和用户空间的映射关系

void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:建立内存映射

参数:

        shmid:共享内存的id

        shmaddr:映射的用户首地址

                        NULL:让操作系统自己寻找用户空间,返回空间首地址

        shmflg:!SHM_RDONLY(可读可写)

返回值:成功:映射的用户空间首地址        失败:NULL

3.写数据

4.读数据

5.解除映射关系

int shmdt(const void *shmaddr);
功能:解除用户映射关系,释放空间

6.删除共享内存

 int shmctl(int shmid, int cmd, struct shmid_ds *buf);

功能:控制共享内存

参数:

        shmid:共享内存id

        cmd:IPC_RMID :删除

        buf:删除不需要使用(NULL)

五.消息队列

1.获取IPC通信的key值

   key_t ftok(const char *pathname, int proj_id);

  功能:获取IPC的key值

  参数:

         pathname:路径                    proj_id:项目ID

  返回值:成功:key                      失败:-1

2.创建消息队列

  int msgget(key_t key, int msgflg);

  功能:根据key值创建一个消息队列

  参数:

        key:IPC的key值

        msgflg:标志位    IPC_CREAT|0664

  返回值:成功:消息队列的id号      失败:-1

3.发送消息

  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

  功能:向消息队列中发送信息

  参数:

        msqid:消息队列的id

        msgp:要发送的消息的结构体首地址

                     struct msgbuf {
                                 long mtype;       /* message type, must be > 0 */
                                  char mtext[1];    /* message data */
                       };

        msgsz:消息体中正文内容大小

        msgflg:标志位:默认0

返回值:成功:0               失败:-1

4.接受消息

  ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);

  功能:从消息队列中接受信息

  参数:

        msqid:消息队列的id

        msgp:存放接收到的消息的结构体首地址

        msgsz:接收的消息体中正文内容大小

        msgtyp:消息的类型

        返回值:成功:实际读到的正文的字节数      失败:-1
5.删除消息队列

  int msgctl(int msqid, int cmd, struct msqid_ds *buf);
 


http://www.kler.cn/a/589515.html

相关文章:

  • Excel VBA实现智能合并重复元器件数据(型号去重+数量累加)
  • VSCode C/C++ 环境搭建指南
  • 云原生服务网格:微服务通信的神经中枢革命
  • 【AI知识管理系统】(一)AI知识库工具测评
  • 美颜SDK x AIGC:如何用滤镜API结合AI生成技术打造创意视觉特效?
  • CI/CD构建与注意事项
  • gazebo报错:[Err] [InsertModelWidget.cc:302] Missing model.config for model
  • 【最佳实践】Go 状态模式
  • 蓝桥杯学习-11栈
  • Gone v2 Tracer 组件-给微服务提供统一的traceID
  • 深入解析Java面向对象三大特征之多态、final、抽象类与接口
  • CMake学习笔记(二):变量设值,源文件/文件查找
  • 网络安全运维应急响应与溯源分析实战案例
  • 【ES6】01-ECMAScript基本认识 + 变量常量 + 数据类型
  • Java高效构建树形结构——异步加载子节点的实现方案
  • “Failed to Load SteamUI.dll” 错误详解:全面解析与高效解决方案,助你快速修复 Steam 客户端问题
  • python拉取大视频导入deepseek大模型解决方案
  • ubuntu20.04下如何防止同一类型串口设备插入USB口无法区分到底是从/dev/ttyUSB0还是/dev/ttyUSB1读取数据
  • Java 8 Stream API:传统实现和流式编程的范式对比
  • 道格拉斯-普克算法