mmap实现进程内写数据和读数据

使用mmap函数可以实现内存映射,腾讯的mmkv就是基于mmap函数实现的匿名共享内存实现的,android中的binder也用到了mmap函数。本文在同一个进程内(进程和子进程间)实现了一个mmap共享内容的demo。
首先声明一个mmap java工具类BinderHelper.java

//BinderHelper.java
package com.example.mmapapp;

public class BinderHelper {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    public native String mmapReadFromJNI();
    public native void mmapWriteToJNI();
}

具体jni代码实现在native-lib.cpp

//native-lib.cpp
#include <jni.h>
#include <string>
#include <fstream>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>


extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_mmapapp_BinderHelper_mmapReadFromJNI(JNIEnv *env, jobject thiz) {
    std::string file = "/sdcard/mybinder";
    int mFd = open(file.c_str(),O_RDWR|O_CREAT,S_IRWXU);
    ftruncate(mFd,4096);//设定文件大小
    int8_t *m_prt = static_cast<int8_t *>(mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, mFd,0));
    char *buf = static_cast<char *>(malloc(100));
    memcpy(buf,m_prt,100);
    std::string result(buf);
    munmap(m_prt,4096);//取消映射
    close(mFd);
    return env->NewStringUTF(result.c_str());
}

extern "C"
JNIEXPORT void JNICALL
Java_com_example_mmapapp_BinderHelper_mmapWriteToJNI(JNIEnv *env, jobject thiz) {
    std::string file = "/sdcard/mybinder";
    int mFd = open(file.c_str(),O_RDWR|O_CREAT,S_IRWXU);
    ftruncate(mFd,4096);//设定文件大小
    int8_t *m_prt = static_cast<int8_t *>(mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, mFd,0));
    std::string data("data from MainActivity");
    memcpy(m_prt,data.data(),data.size());
}

主进程在MainActivity.java中使用mmap向内存中写数据,然后跳转到子进程SecondActivity.java

//MainActivity.java
package com.example.mmapapp;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    BinderHelper mBinderHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBinderHelper = new BinderHelper();
        initPermission();
    }

    private void initPermission() {
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},200);
    }


    public void write(View view) {
        mBinderHelper.mmapWriteToJNI();
        startActivity(new Intent(MainActivity.this,SecondActivity.class));
    }
}

子进程SecondActivity.java使用相同的路径和mmap函数去读数据并正确显示到界面上

//SecondActivity.java
package com.example.mmapapp;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class SecondActivity extends AppCompatActivity {
    private BinderHelper mBinderHelper;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        mTextView = findViewById(R.id.txt);
        mBinderHelper = new BinderHelper();
        initPermission();
    }

    private void initPermission() {
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},200);
    }

    public void read(View view) {
        mTextView.setText(mBinderHelper.mmapReadFromJNI());
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
***存储映射区来实现进程间的通信。存储映射区是指将一个文件或者匿名映射关联到进程的地址空间中,使得进程可以通过访问内存的方式来读写文件或者进行进程间的通信。 在父子进程之间,可以通过打开的文件和使用mmap建立的存储映射区来实现通信。父子进程的内存空间遵循读时共享、写时复制的原则,所以打开的文件和mmap建立的存储映射区在父子进程之间是一直共享的。可以通过修改存储映射区中的数据来进行进程间的通信。 另外,在非血缘关系的进程间,也可以通过mmap实现通信。使用宏MAP_ANON(仅linux独有)或者指定文件描述符为-1,可以创建匿名映射区,无需依赖文件。这种方式可以实现非血缘关系进程间的通信,但仅限于同一台机器上的进程。 综上所述,mmap可以通过建立存储映射区来实现进程间的通信,无论是父子进程还是非血缘关系的进程。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [利用 mmap 实现进程之间的通信](https://blog.csdn.net/qq_40843865/article/details/89442987)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值