Linux高级编程:进程间的通信(二)、IPC

回顾

共7种方式:

古老的进程间通信方式:

        管道:

                无名管道

                有名管道

        信号

系统V IPC进程对象

        共享内存

        消息队列

        信号量集

socket通信  //网络

-------------------------

无名管道

        pipe()

特点:

        用于亲缘关系进程间

     (继承相关的文件描述符 -- 对应实际同一个管道)

管道的特点:

        1.形成的数据流

        2.FIFO(first in first out ) // -- 数据结构的特点 -- 队列(排队)

           FIFO (first in last out)//  栈的特点

        3.管道中的的数据,读取之后,就没有了

管道读写规则:

        a.读端存在,写管道

        b.独断不存在,写管道 --- 股电脑破裂  SIGPIPE 信号 --- 进程收到这信号后会被结束掉

        c.写段存在,读管道 --- 没数据,读操作阻塞

        d.写端变速存在,读管道 -- 没数据,读操作不阻塞, 立即返回  返回0 表示没数据

有名管道:

创建

        mkfifo // 在系统中创建了一个 管道文件的名字

                   // 不同的进程(毫无亲缘关系的进程)可以通过该名字  最终操作到同一个管道进而实现通信

------------------------------------------

信号通信:

 

异步、同步:

用户自定义操作:

signal   

       #include <signal.h>

       typedef void (*sighandler_t)(int);

                        // ===》void (*xx)(int); == void fun(int);
                           ===》xx是 void fun(int) 类型函数的函数指针
                           ===》typedef void(*xx)(int)   sighandler_t;

       sighandler_t signal(int signum, sighandler_t handler);

        功能:

                用于向操作系统注册信号处理函数,以便在特定信号发生时执行相应的操作。

        参数:

                 @signum 是信号编号,它是一个整数,用于指定要处理的信号。

       @handler是一个函数指针,它指向的信号处理函数将在接收到 signum 指定的信号时被                                   调用。       

  • 当handler为SIG_IGN时,表示忽略此信号(需要注意的是,SIGKILLSIGSTOP信号不能被忽略)。
  • 当handler为SIG_DFL时,表示接到此信号后的动作是系统默认动作。
  • 当handler是一个函数地址时,表示当接收到对应编号的signo信号时,执行该函数。

        返回值:

       signal函数的返回值也是一个 sighandler_t 类型的函数指针,它指向之前注册        在 signum 上的信号处理函数。如果注册失败,signal 函数将返回 SIG_ERR

                

练习:

1、自定义处理信号10和12

#include<stdio.h>
#include<unistd.h>
#include<signal.h>void handler_10_12(int sno)
{printf("recieve %d\n",sno);
}int main(int argc, const char *argv[])
{if(signal(SIGUSR1,handler_10_12) == SIG_ERR){perror("signal fail");return -1;}if(signal(SIGUSR2,handler_10_12) == SIG_ERR){perror("signal fail");return -1;}while(1){printf("hello\n");sleep(1);}return 0;
}

2、通过信号处理的方式,回收僵尸态子进程   // 异步处理收尸,不阻碍父进程的操作

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
#include <sys/wait.h>void do_wait(int sno)
{wait(0);printf("child wait\n");
}int main(int argc, const char *argv[])
{if(signal(SIGCHLD,do_wait) == SIG_ERR){perror("signal fail");return -1;}pid_t pid = fork();if(pid < 0){perror("fork fail");return -1;}if(pid > 0){int i = 0;while(1){printf("father = %d\n",i++);sleep(1);}}if(pid == 0){int i = 0;while(1){printf("child = %d\n",i++);sleep(1);}}return 0;
}

3、

函数: alarm();  计数  括号内写秒数,到时发送SIGALRM信号  则说明超时1次。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>int count;void handler(int signo)
{printf("---signal---%d\n",++count);;if(count == 3){printf("---timeout---\n");exit(0);}alarm(3);
}int main(int argc, const char *argv[])
{alarm(3);char buf[1024] = {0};signal(SIGALRM,handler);while(1){fgets(buf,sizeof(buf),stdin);count = 0;alarm(3);}return 0;
}

kill   

      #include <sys/types.h>
      #include <signal.h>

      int   kill(pid_t pid, int sig);
            功能:通过该函数可以给pid进程发送信号为sig的系统信号。
            参数:   @pid 要接收信号的进程pid
                          @sig 当前程序要发送的信号编号 《=== kill  -l
            返回值: 成功 0
                            失败  -1;

raise

        int raise(int sig)<==> kill(getpid(),int sig);  
            功能:给进程自己发送sig信号

pause

        int pause(void);
            功能:
                 进程暂停,不再继续执行,除非收到其他信号。

IPC对象:


(*)共享内存 //进程间效率最高的通信方式

shm,sem,msg

    system v :  共享内存  信号量集

    IPC对象操作通用框架:
    0x  ftok
    key值 ==> 申请 ==》读写 ==》关闭 ==》卸载

    
    key值    // 
    申请  -- xxxget  //key <--> ipc对象 
    读写 
    关闭 
    卸载

key值:===》唯一键值
创建方式有三种:

1、IPC_PRIVATE 固定的私有键值,其值等于 0x0
        一般用于有亲缘关系的进程间使用。

2、ftok()创建临时键值。


            #include <sys/types.h>
            #include <sys/ipc.h>
            key_t ftok(const char *pathname, int proj_id);
                    功能:通过该函数可以将pathname指定的路径用来以
                               proj_id生成唯一的临时键值。
                    参数:@pathname 路径+名称===》任意文件,只要不会
                               被删除重建即可。
                               @proj_id  整形的数字,一般用ASCII码的单字符
                                表示与参数1的运算。

                    返回值:成功 返回唯一键值
                                  失败  -1;

申请:

1、申请对象:shmget()
            

            #include <sys/ipc.h>
            #include <sys/shm.h>
                        ps aux|grep a.out
                        shared memory get         IPC_CREAT|0666
            int shmget(key_t key, size_t size, int shmflg);
                    功能:
                          使用唯一键值key向内核提出共享内存使用申请
                    参数:

                          @key   唯一键值
                          @size  要申请的共享内存大小
                          @shmflg 申请的共享内存访问权限,八进制表示
                                  如果是第一个申请,则用IPC_CREAT
                                  如果要检测是否存在,用IPC_EXCL
                    返回值:
                            成功 返回共享内存id,一般用shmid表示
                            失败  -1;

2、映射对象:shmat()
    

        void *shmat(int shmid, const void *shmaddr, int shmflg);
            功能:将指定shmid对应的共享内存映射到本地内存。
            参数:

                     @shmid 要映射的本地内存
                     @shmaddr 本地可用的地址,如果不确定则用NULL,表示
                                由系统自动分配。
                     @shmflg  
                                   0         ,  表示读写
                                   SHM_RDONLY, 只读
            返回值:
                         成功 返回映射的地址,一般等于shmaddr
                         失败 (void*)-1

3、删除对象:shmctl
    

        int shmctl(int shmid, int cmd, struct shmid_ds *buf);
            功能:
                       修改共享内存属性,也可以删除指定的共享内存对象。
            参数:@shmid 要删除的共享内存对象
                       @cmd 
                       @IPC_RMID 删除对象的宏
                       @buff  NULL 表示只删除对象。
            返回值:成功 0
                           失败 -1

练习:

// a
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<unistd.h>
#include <signal.h>int main(int argc, const char *argv[])
{key_t key = ftok("/",'A');if (key < 0){perror("ftok fail");return -1;}int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid < 0){perror("shmget fail");return -1;}void *p = shmat(shmid,NULL,0);if(p == (void *)-1){perror("shmat fail");return -1;}pid_t *pid = p;pid_t pid_b = *pid;printf("pid_b = %d\n",pid_b);while(1){fgets(p,1024,stdin);kill(pid_b,10);printf("p = %s\n",(char *)p);if(strncmp((char *)p,"quit",4) == 0){break;}}return 0;
}//b
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>void handler(int signo)
{}int main(int argc, const char *argv[])
{key_t key = ftok("/",'A');if (key < 0){perror("ftok fail");return -1;}int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid < 0){perror("shmget fail");return -1;}void *p = shmat(shmid,NULL,0);pid_t *pid = p;*pid = getpid();printf("pid = %d\n",*pid);if(p == (void *)-1){perror("shmat fail");return -1;}signal(SIGUSR1,handler);while(1){	pause();printf("p = %s\n",(char *)p);if(strncmp((char *)p,"quit",4) == 0){break;}}return 0;
}

消息队列 

信号量集

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker镜像导出/导入

Docker镜像导出/导入 一、前言 在实际操作中&#xff0c;为了便于docker镜像环境和服务配置的迁移&#xff0c;我们有时需要将已在测试环境主机上完成一系列配置的docker镜像或运行中的容器镜像导出&#xff0c;并传输到生产或其他目标环境主机上运行。为此&#xff0c;本文主…

Vue.js 进阶技巧:keep-alive 缓存组件解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

php反序列化字符逃逸

php反序列化和序列化 PHP序列化&#xff1a;serialize() 序列化是将变量或对象转换成字符串的过程&#xff0c;用于存储或传递 PHP 的值的过程中&#xff0c;同时不丢失其类型和结构。“序列化”是一种把对象的状态转化成字节流的机制 类似于这样的结构&#xff1a; O:4:&quo…

安装Proxmox VE虚拟机平台

PVE是专业的虚拟机平台&#xff0c;可以利用它安装操作系统&#xff0c;如&#xff1a;Win、Linux、Mac、群晖等。 1. 下载镜像 访问PVE官网&#xff0c;下载最新的PVE镜像。 https://www.proxmox.com/en/downloads 2. 下载balenaEtcher balenaEtcher用于将镜像文件&#…

Ps:图案图章工具

图案图章工具 Pattern Stamp Tool可将各种预设图案或自定义的图案&#xff0c;通过画笔涂抹的方式填充到图像中。 快捷键&#xff1a;S 图案图章工具提供了一种快速、灵活的方式来为图像局部添加纹理和装饰。 这个工具类似于仿制图章工具&#xff0c;但区别在于&#xff0c;它使…

蓝桥杯集训·每日一题2024 (差分)

前言&#xff1a; 差分笔记以前就做了&#xff0c;在这我就不再写一遍了&#xff0c;直接上例题。 例题&#xff1a; #include<bits/stdc.h> using namespace std; int a[10009],b[100009]; int main(){int n,ans10,ans20;cin>>n;for(int i1;i<n;i){cin>>…

【Flutter 面试题】在flutter里streams是什么?有几种streams?有什么场景用到它?

【Flutter 面试题】在flutter里streams是什么&#xff1f;有几种streams&#xff1f;有什么场景用到它&#xff1f; 文章目录 写在前面解答补充说明**Single subscription streams** 读取文件广播流 Broadcast streams 通知多个监听器关于状态的变化 写在前面 关于我 &#xf…

(十六)【Jmeter】取样器(Sampler)之测试活动(Test Action)

简述 操作路径如下: JMeter中的测试活动取样器实际上并不是一个具体的取样器类型,而是一种对测试计划中的多个取样器进行组合和执行的活动。常常被用作定时器,在某个请求之后等待多长时间。 参数说明 Logical Action on Thread(在线程上的逻辑操作) Pause Duration(mil…

C 嵌入式系统设计模式 20:队列模式

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之六…

C语言回顾学习

一、数据类型 1.常量 2.float浮点表示 3.字符型 4.char&#xff08;大小写&#xff09; #include <stdio.h> //根据数字输出字符--int值可以直接输出为char int main() {int value;while (1){scanf("%d",&value);if(value<65||value>122){printf(&…

C# OpenCvSharp DNN 部署yolov3目标检测

目录 效果 yolov3.cfg 项目 代码 下载 C# OpenCvSharp DNN 部署yolov3目标检测 效果 yolov3.cfg [net] # Testing #batch1 #subdivisions1 # Training batch16 subdivisions1 width416 height416 channels3 momentum0.9 decay0.0005 angle0 saturation 1.5 exposure 1…

[linux] 使用 kprobe 观察 tcp 拥塞窗口的变化

tcp 中拥塞窗口用来做拥塞控制。 在发送侧&#xff0c;要发送数据的时候会基于拥塞窗口进行判断&#xff0c;当前这个包还能不能发送出去。 tcp 发包函数是 tcp_write_xmit()&#xff0c;在这个函数中调用 tcp_cwnd_test() 来判断当前拥塞窗口让不让发包。从 tcp_cwnd_test() 函…

「滚雪球学Java」:多线程(章节汇总)

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

个人安全团队官方引导单页

一款简洁大气得个人团队引导html单页,非常不错,背景图和LOGO支持自行更改替换,可以拿来做为团队官网,只是单页没有后台,感兴趣得小伙伴可以下载体验一下! 下载地址 https://www.qqmu.com/2380.html

【Spring云原生】Spring官宣,干掉原生JVM,推出 Spring Native!整体提升性能!Native镜像技术在Spring中的应用

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &#x1f680; 本…

tomcat优化、nginx +tomcat 部署 (三)

在目前流行的互联网架构中&#xff0c;Tomcat在目前的网络编程中是举足轻重的&#xff0c;由于Tomcat的运行依赖于JVM&#xff0c;从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分 Tomcat 是一个流行的开源 Java 服务器&#xff0c;用于托管 Java …

滤波和卷积的区别

本文主要介绍滤波和卷积的区别&#xff0c;以供读者能够理解该技术的定义、原理、应用。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;计算机杂记 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&…

java010 - Java面向对象基础

1、类和对象 1.1 什么是对象 万物皆对象&#xff0c;客观存在的事物皆为对象。 1.2 什么是面向对象 1.3 什么是类 类是对现实生活中一类具有共同属性和行为的事物抽象。 特点&#xff1a; 类是对象的数据类型类是具有相同属性和行为的一组对象的集合 1.4 什么是对象的属…

k8s 1.28.x node资源预留

当前NOde的配置 默认位置如下: vim /var/lib/kubelet/config.yaml #再最后添加如下&#xff0c;参加应该大家一看就明白什么意思&#xff0c;不做多解释了 #max-pods: 230 evictionHard:memory.available: 100Minodefs.available: 10%nodefs.inodesFree: 5% kubeReserved:cpu:…

多多关键字API php java Python

多多关键字API接口广泛应用于商家进行市场分析、竞品分析、关键词优化等场景。商家可以通过分析关键词数据&#xff0c;了解用户需求&#xff0c;制定针对性的营销策略&#xff0c;提高产品的曝光率和转化率。 多多-item_seach-通过关键字搜索商品列表 公共参数 获取key和秘钥…