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

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);
 

相关文章:

  • 单元测试、注解
  • c++入门基本知识掌握
  • SpringBoot集成Netty的方案以及Demo示列
  • SAP HANA on AWS Amazon Web Services
  • Git 面试问题,解决冲突
  • k8s常用操作 (一) ---根据上一篇文章用到写的 不全
  • __call__
  • fastpdf应用程序错误0xc0000142
  • 反汇编学习
  • 基于YOLOv8与SKU110K数据集实现超市货架物品目标检测与计算
  • Matlab 单球机器人动力学与LQR控制研究
  • P11229 [CSP-J 2024] 小木棍
  • 跳转到视图文件夹
  • 如何展示一个类的所有方法
  • ArcGIS Pro中加载在线地图的详细指南
  • 利用AI让数据可视化
  • Python中的“泛型”和“多重继承”
  • uniapp报错 Right-hand side of ‘instanceof‘ is not an object
  • rust笔记14:mod和use的使用区别
  • 学习笔记 ASP.NET Core Web API 8.0部署到iis
  • 警方通报男子广州南站持刀伤人:造成1人受伤,嫌疑人被控制
  • 娃哈哈:调整产销布局致部分工厂停工,布局新产线可实现自主生产,不排除推新品牌
  • 宜昌谱写新叙事:长江大保护与高质量发展如何相互成就
  • 30平米的无障碍酒吧里,我们将偏见折叠又摊开
  • 秘鲁总统任命前司法部长阿拉纳为新总理
  • 冰雹造成车损能赔吗?如何理赔?机构答疑