android Framework 中用到了哪些跨进程通信方式?

news2024/10/6 8:36:54

文章目录

    • Linux 有哪些跨进程的通信方式?
    • 管道
    • 本地 Socket
    • 共享内存
    • 信号

Linux 有哪些跨进程的通信方式?

  • Binder 机制是Android基于Linux的一种独特的IPC机制。我们常用的AMS,PMS 等都是通过Binder机制来完成跨进程通信的,那么除了Binder ,Linux 还有其他跨进程通信的方式可以选择。在Android Framework中主要用到以下方式

      1. 管道
      2. Socket
      3. 共享内存
      4. 信号
    

管道

  • 管道的特点:半双工的,单向

    管道描述符数据只能往一个方向,要么read要么write。如果向既可以读又可以写,则需要两个描述符才可以。Linux 基于这种情况提供了 pipe(fds) api,这个api可以生成一对描述符,一个用来写,一个用来读。

  • 一般是在父子进程之间使用

    无名管道一般是在父子进程之间使用。如果是有名管道,只要两个进程之间都知道名字就可以直接通信了。

  • 管道的使用方式
    在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
 
 
int main()
{
int n,fd[2];                         // 这里的fd是文件描述符的数组,用于创建管道做准备的
pid_t pid;
char line[100];
if(pipe(fd)<0)                     //   创建管道,生成描述符 fd[1] 是用来写的 fd[0] 是用来读的
   printf("pipe create error/n");
 
if((pid=fork())<0)              //利用fork()创建新进程
    printf("fork error/n");
 
else if(pid>0){                   //这里是父进程,先关闭管道的读出端,然后在管道的写端写入“hello world"
    close(fd[0]);
    write(fd[1],"hello word/n",11);
}
else{
    close(fd[1]);                 //这里是子进程,先关闭管道的写入端,然后在管道的读出端读出数据
   n= read(fd[0],line,100);
    write(STDOUT_FILENO,line,n);
}
exit(0);
}
  • Framework 中 在Android 4.4 中 Looper 中使用到了管道,高版本更换了 eventfd 的方式。当有线程拿到写的描述符,往里写内容,那么读端就可以收到通知了。
Looper::Looper(bool allowNonCallbacks) :
        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
        mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
    int wakeFds[2];
    // 通过pipe 生成两个描述符
    int result = pipe(wakeFds);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
	// 0 元素对应的是 读
    mWakeReadPipeFd = wakeFds[0];
    // 1 对应的是写 
    mWakeWritePipeFd = wakeFds[1];
    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    mIdling = false;
    // Allocate the epoll instance and register the wake pipe.
    mEpollFd = epoll_create(EPOLL_SIZE_HINT);

    struct epoll_event eventItem;
    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
    eventItem.events = EPOLLIN;
    eventItem.data.fd = mWakeReadPipeFd;
    // 通过 epoll_ctl 注册事件监听
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
}
  • epoll 是怎么监听读端事件的
int Looper::pollInner(int timeoutMillis) {
	// 。。。
	struct epoll_event eventItems[EPOLL_MAX_EVENTS];
	// epoll_wait 阻塞在这,当返回的时候 eventCount 代表有几个事件被触发了
    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
	// 然后依次处理
	
	   for (int i = 0; i < eventCount; i++) {
        int fd = eventItems[i].data.fd;
        uint32_t epollEvents = eventItems[i].events;
        // 判断描述符 mWakeReadPipeFd ,如果是读描述符
        if (fd == mWakeReadPipeFd) {
            if (epollEvents & EPOLLIN) {
            	// 从管道中读取数据
                awoken();
            } 
        } else {
            // ... 
        }
    }
}
  • 往管道中写数据,通过 Looper 的 wake() 函数写
void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
    ALOGD("%p ~ wake", this);
#endif

    ssize_t nWrite;
    do {
    	// 通过写描述符写
        nWrite = write(mWakeWritePipeFd, "W", 1);
    } while (nWrite == -1 && errno == EINTR);

    if (nWrite != 1) {
        if (errno != EAGAIN) {
            ALOGW("Could not write wake signal, errno=%d", errno);
        }
    }
}

管道在进程内可以用,跨进程也可以用,可以和 epoll 相结合监听读写事件,一般用在数据量不大的跨进程通信中使用。

本地 Socket

  • Socket 特点

      全双工,既可以读也可以写
      两个进程之间可以无亲缘关系
    
  • Android Framework 中在 Zygote 中,通过 Socket 来接收 AMS 请求,启动应用进程。在 ZygoteInit 的入口函数中

public static void main(String argv[]) {
            // 注册 Zygote 的 socket 监听接口,用来接收启动应用程序的消息
            zygoteServer.registerServerSocketFromEnv(socketName);
            // 通过调用 runSelectLoop 进入监听和接收消息的环节 里面有一个 while (true) 
            caller = zygoteServer.runSelectLoop(abiList);
}
  • Runnable runSelectLoop(String abiList)  处理和返回Socket数据
    
Runnable runSelectLoop(String abiList) {

	while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            // 。。。
            try {
            //	 用来检测有没有事件发生
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
			if (i == 0) {
                    // 处理新来的连接
           } else {
					// 处理发过来的数据
			}
	}

}

共享内存

  • 共享内存的特点

      1. 很快,不需要多次拷贝。上面提到的管道和Socket数据量太大会很糟,因为会拷贝两次数据。
      共享内存拿到文件描述符后,把它同时交给两个进程,就可以进行通信了。
      2. 进程之间也不用存在亲缘关系
    
  • 具体匿名共享内存看之前的文章

  1. 匿名共享内存 ashmem
  2. 跨进程通信–共享内存(ashmem)实例

信号

  • 特点

      1. 单向发送:不关心发出去之后的事
      2. 只能带一个信号,不能带别的参数
      3. 知道进程 pid 就可以发信号了,而且可以群发信号
    
  • 哪里用到了信号?看下面的代码,大多数人都见过,一般我们安装或者重启应用的时候可能先kill掉自己。

android.os.Process.killProcess(android.os.Process.myPid())

killProcess 中就发送了一个信号

	public static final native void sendSignal(int pid, int signal);
	
    public static final void killProcess(int pid) {
        sendSignal(pid, SIGNAL_KILL);
    }
static void SetSigChldHandler() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa)); //对sa地址内容进行清零操作
  sa.sa_handler = SigChldHandler;
  // zygote 关注的SIGCHLD信号,如果进程杀死了好及时回收资源
  int err = sigaction(SIGCHLD, &sa, NULL);
}

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

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

相关文章

维格云连接功能日志入门教程

目录 维格云连接功能简介 维格云连接功能效果 涉及功能范围 注意事项 维格云连接功能简介 应用内「数据管理——概览」界面,新增了连接功能日志模块,便于查看连接功能的执行结果、排查问题。 维格云连接功能效果 鼠标移动至目标日志,点击“查看数据”可以跳转至对应数据…

求树的直径算法以及证明

以下为两次dfs&#xff08;bfs&#xff09;的做法以及正确性证明。 算法步骤 &#xff08;1&#xff09;任取树上一点S&#xff0c;以S为源点BFS得S到各个顶点的d值&#xff1b; &#xff08;2&#xff09;取d值最大者之一为P&#xff0c;再以P为源点BFS得P到各个顶点的d值&am…

Metabase学习教程:仪表盘-7

使用Metabase构建记录查找工具 如何使用Metabase构建内部查找工具来快速查找有关客户、订单或其他数据的详细信息。 我们写过人们使用Metabase的一些有趣的方式其中之一是使用Metabase作为内部或后台应用程序的解决方案&#xff0c;例如客户查找工具。您不必构建定制页面来查…

惠普笔记本重装系统后没有声音如何解决

​最近很多小伙伴又开始了网上冲浪的生活,但是电脑用久了难免会发生一些故障的问题,最近就有些小伙伴重装系统之后问小编自己的电脑没有声音的问题?不要慌?接下来小编教你惠普笔记本重装系统后没有声音的解决方法. 工具/原料&#xff1a; 系统版本&#xff1a;win7系统 型…

基于单片机技术的自动停车器的设计

目 录 摘 要 I Abstract II 1绪论 1 1.1课题研究背景 1 1.2国内外发展现状 1 1.3汽车自动停车器的研究目的 2 1.4课题研究的意义 2 2汽车停车器的功能设计 3 2.1汽车自动停车器的设计要求 3 2.2停车器的主要功能 3 3汽车自动停车器的硬件设计 5 3.1汽车自动停车器的硬件组成 5 …

简单的 JSONParser

最近在学习 Python 的正则表达式内容&#xff0c;我看的是官方的文档&#xff0c;在文档的最后有一个例子&#xff0c;勾起了我的兴趣。它是用正则表达式来制作了一个简单的词法分析器。我觉得这个东西非常有趣&#xff0c;以前在学校的时候&#xff0c;有一次作业我是手写的&a…

开源?Highcharts JS 10.3.2 | Highcharts Javascript

Highsoft 是 Highcharts Javascript 图表库及其同类产品 Highcharts Stock、Highcharts Maps 和 Highcharts Gantt 背后的公司。 Highcharts 是一个多平台图表库&#xff0c;它使开发人员可以轻松地将交互式图表添加到任何规模的 Web 和移动项目中。 世界上最大的 100 家公司中…

36氪专访融云CEO董晗:8年企服,6年出海,现计划成为「沙特最大科技企业」

⬆️关注文章公众号文章报名融云&艾瑞“政企数智办公研究报告及新品发布会” 若从 2001 年中国加入 WTO 算起&#xff0c;中国企业走向海外的进程已经持续了二十余年。但由于行业起步较晚&#xff0c;国内企服领域的全球化&#xff0c;直到今年才渐成趋势。关注【融云全球互…

aws cloudformation 理解宏的使用

资料 使用 AWS CloudFormation 宏对模板执行自定义处理Macros Examples使用 AWS Lambda 支持的宏扩展 AWS CloudFormation 宏的理解 在cfn模板的创建过程中&#xff0c;我们会使用内置函数和伪函数对配置参数进行进一步处理&#xff0c;避免冗长的写法&#xff0c;更灵活的配…

西门子精彩触摸屏SMART V3组态报警的具体方法示例

西门子精彩触摸屏SMART V3组态报警的具体方法示例 用户自定义报警分为离散量报警和模拟量报警。 离散量报警:离散量对应于二进制数的1位,离散量的两种相反状态可以用1位二进制数的0、1状态来表示。例如:电动机的交流接触器的接通和断开、各种故障信号的出现和消失,都可以用…

建模助手:Revit中梁注释设置表达相对净高

一、Revit中梁注释设置表达相对净高 当我们利用 Revit 软件做管综的时候&#xff0c;需要明确与结构体的相对位置关系&#xff0c;下面我们就用“梁标记”的方式来做一下标记&#xff0c;在平面图上表达一下相对净高。如下图&#xff1a; 这样的平面梁标注是如何做上去的呢? 首…

获取网络时间、解析xml、截取string

很多游戏具有每日登陆奖励功能&#xff0c;为防止玩家修改本地时间&#xff0c;需要读取服务器时间。下面分两部分介绍获取网络时间的两种方法&#xff0c;第一部分解析xml&#xff0c;第二部分截取string。 第一部分&#xff1a;通过国家授时中心链接获得的数据如下: 获取网络…

互联网+医疗解决方案

国家“互联网”行动指导意见&#xff0c;明确“互联网医疗健康”行动路线。 制定“互联网”行动计划&#xff0c;推动移动互联网、云计算、大数据、物联网等与现代制造业结合&#xff0c;促进电子商务、工业互联网和互联网金融健康发展&#xff0c;引导互联网企业拓展国际市场…

麒麟信安携手河南IT联盟召开 《麒麟信安信创应用解决方案》线上分享会

在党政及金融、交通、能源等重要行业的信创应用步伐逐步加快的背景下&#xff0c;各行业均面临着不同程度的国产化落地难题。11月29日下午&#xff0c;麒麟信安与河南省信息协会IT产业分会&#xff08;河南IT联盟&#xff09;携手召开《麒麟信安信创应用解决方案》线上分享会&a…

微信小程序| 做一款可以计算亲戚关系的计算器

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …

Spring(Spring的理解+DI+Spring的创建)

目录 1. Spring 是什么 2. DI 3. 面试题: IoC 和 DI 有什么区别? 4. Spring 的创建 5. 将 Bean (对象) 存储到 Spring (容器) 中 6. 将 Bean (对象) 从 Spring (容器) 中取出来 7. 面试题: ApplicationContext 和 BeanFactory的区别 8. getBean 更多用法 1. Spring 是…

能否在虚拟平台里构建真实的生活体验?

接近三年的疫情&#xff0c;重构了每一个人的生活。线下活动的频繁延期、取消&#xff0c;使得物理空间的聚集充满了不确定性&#xff0c;线上办公、网络授课等远程协同的方式在这样的时代背景下&#xff0c;毫无疑问成了主旋律。曾经只停留在想象层面的不出门就能完成工作、上…

u盘打不开常见原因|数据恢复方法|解决方案

u盘作为一种常用的外部存储器&#xff0c;能够帮助我们存放大量的数据&#xff0c;如图片、文档、视频等文件类型。但是在使用过程中&#xff0c;难免会遇到这样或那样的问题&#xff0c;比如使用过程中出现u盘打不开的情况&#xff0c;但是里面又有自己重要的文件&#xff0c;…

数字图像处理(入门篇)一 图像的数字化与表示

目录 1 人眼图像是如何形成的&#xff1f; 2 图像的感知与获取&#xff1f; 3 图像的数字化 4 数字图像的表示 1 人眼图像是如何形成的&#xff1f; 人眼近似为一个球体&#xff0c;物体的光线经过角膜和晶状体的折射&#xff0c;在视网膜上形成“倒立缩小”的实像。 视网膜…

这或许是全网最详细的介绍预言机赛道的视频课程,通俗易通,有趣有料!

图片来源&#xff1a;由无界版图 AI 绘画工具生成有一句话在创业者中很流行&#xff1a;Web3创业三大坑&#xff0c;隐私、跨链、预言机……搞塌加密市场的DK和SBF还在豪华度假酒店里思考人生搞隐私&#xff0c;一毛钱没赚到的Tornado cash开发者却在吃牢饭……加密圈前十大资产…