之前对AIDL用的不是很多,今天抽时间对其做一下详细的了解,下面本人主要从以下几个方面对AIDL做一下总结:

1.什么是AIDL?

2.为什么Android中要有AIDL?

3.什么时候使用AIDL?

4.具体怎么实现AIDL?

下面我们就进入今天的分析,分析代码Demo会在最后附上下载地址。

一.那么首先什么是AIDL呢?

AIDL全称为Android Interface definition language,顾名思义它是一种Android内部进程通信接口的描述语言,他妈怎么这么绕啊,简单的说它就是Android进程(现在可以先知道每一个App就是一个单独的进程【一个App也可以定义不同的进程】)间通信的桥梁,通过它我们可以定义进程间的通信接口(通过它我们可以在进程间进行相互操作)。

 

二.为什么Android中要有AIDL呢?

因为Android中进程与进程之间是不能相互访问的,每一个进程只能访问自己进程内的数据及操作,每一个进程都有自己的Dalvik VM实例,都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行自己的操作,相互之间不能通信。

三.什么时候使用AIDL?

Android官方文档介绍AIDL中有这么一句话:【Note: Using AIDL is necessary onlyif you allow clients from different applications to access your servicefor IPC and want to handle multithreading in your service. If youdo not need to perform concurrent IPC across different applications, you should create yourinterface by implementing a Binder or,if you want to perform IPC, butdo not need to handle multithreading, implement yourinterface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.】只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时你才必须使用AIDL,其他情况下你都可以选择其他方法,如使用Messager,也能跨进程通讯。可见AIDL是处理多线程、多客户端并发访问的。而Messager是单线程处理。

四.怎么实现AIDL?

下面AIDL我们分成两步:

1.Server端代码编写,及为我们提供服务的一端,比如我们有好几个App,有一个App中有一个超牛逼的算法,我们另外几个App中也要用这个算法,这个Server端就是提供算法的那个App。

2.编写Client端代码,Client端为其他几个App。

1.下面我们看一下第一步:server端代码编写。

我们以客户端将两个int值传递给服务端,服务端进行相加后返回为例:

AS中新建一个项目,创建过程跟普通项目没有区别。然后创建我们的*.aidl文件,名称可以自己定,我这里就叫IMyAidlInterface.aidl,在我们新建项目的app文件路径上右键new->AIDL->AIDL File,如下图:

创建成功的话会在项目中新增如下目录结构:

可以看见与java同级出现了一个aidl目录,其下边的包路径与java包路径相同,再看我们新创建的.aidl文件内容,默认会有一个void basicTypes()方法,其中参数为aidl支持的几种传参基本数据类型(Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),如果要传递自定义类型,首先要让自定义类型支持parcelable协议),然后我们可以删掉默认方法,添加我们自己的方法,如下:

然后Build->rebuild project,在之前eclipse中会自动生成.java文件,AS不行,我们必须重新编译一下项目,然后会在如下文件目录结构中出现我们梦寐以求的.java文件。

其代码如下:

/** This file is auto-generated.  DO NOT MODIFY.* Original file: D:\\lylsoft\\android\\androidstudio\\mydemo\\AidlClient\\app\\src\\main\\aidl\\com\\jason\\aidl\\aidldemo\\IMyAidlInterface.aidl*/
package com.jason.aidl.aidldemo;
// Declare any non-default types here with import statements
public interface IMyAidlInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.jason.aidl.aidldemo.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.jason.aidl.aidldemo.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/*** Cast an IBinder object into an com.jason.aidl.aidldemo.IMyAidlInterface interface,* generating a proxy if needed.*/
public static com.jason.aidl.aidldemo.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.jason.aidl.aidldemo.IMyAidlInterface))) {
return ((com.jason.aidl.aidldemo.IMyAidlInterface)iin);
}
return new com.jason.aidl.aidldemo.IMyAidlInterface.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.jason.aidl.aidldemo.IMyAidlInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int add(int a, int b) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int add(int a, int b) throws android.os.RemoteException;
}

可以看到,在我们编译的出的.java文件中有一个Stub内部类,我们在MainActivity同目录下创建一个Service,创建一个Stub类实现add()方法后在onBind()方法中返回,代码如下:

package com.jason.aidl.aidldemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.jason.aidl.aidldemo.Person;public class MyAidlService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i("Log_LYL", "Onstart");return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {return stub;}IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {@Overridepublic int add(int a, int b) throws RemoteException {return a + b;}};
}

到这里我们的Server端代码就完成了?没有,我们要知道,我们其他项目中没有这个Service,所以我们要想在其他App中打开这个service必须通过隐式意图,所以我们必须在我们的Manifest.xml中添加一个action,如下:

<serviceandroid:name=".MyAidlService"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.lyl.aidl"/></intent-filter>
</service>

到这里服务端工作算是基本完成了。

2.下面看第二步编写Client端代码。

新建一个Client端项目,我们将服务端整个aidl下的文件统统考本到Client端与java同级目录下,如下图:

编译项目后会在Client端也生成一个.java文件,且与Server端生成的.java文件一模一样,然后我们就可以在我们的activity_main.xml中布局,然后在MainAcitivity中进行绑定service进行远程调用运算了,xml代码与activity代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="客户端"android:textColor="@android:color/holo_red_dark"android:textSize="15sp" /><EditTextandroid:id="@+id/et_num1"android:layout_width="200dp"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/et_num2"android:layout_width="200dp"android:layout_height="wrap_content" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="add"android:text="加运算" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="结果:" /><TextViewandroid:id="@+id/tv"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="2" /></LinearLayout>
</LinearLayout>
package com.jason.aidl.client.aidlclient;import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;import com.jason.aidl.aidldemo.IMyAidlInterface;import java.util.List;public class MainActivity extends AppCompatActivity {private EditText et_num1, et_num2;private TextView tv;private IMyAidlInterface mService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);et_num1 = (EditText) findViewById(R.id.et_num1);et_num2 = (EditText) findViewById(R.id.et_num2);tv = (TextView) findViewById(R.id.tv);Intent intent = new Intent();intent.setAction("com.lyl.aidl");Intent intent1 = new Intent(createExplicitFromImplicitIntent(this, intent));bindService(intent1, mServiceC, Context.BIND_AUTO_CREATE);}public void add(View v) {int a = Integer.valueOf(et_num1.getText().toString());int b = Integer.valueOf(et_num2.getText().toString());try {int res = mService.add(a, b);tv.setText(res+"");} catch (RemoteException e) {e.printStackTrace();}}ServiceConnection mServiceC = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mService = IMyAidlInterface.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {}};/*** 兼容Android5.0中service的intent一定要显性声明** @param context* @param implicitIntent* @return*/public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {// Retrieve all services that can match the given intentPackageManager pm = context.getPackageManager();//通过queryIntentActivities()方法,查询Android系统的所有具备ACTION_MAIN和CATEGORY_LAUNCHER//的Intent的应用程序,点击后,能启动该应用,说白了就是做一个类似Home程序的简易Launcher 。List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);// Make sure only one match was foundif (resolveInfo == null || resolveInfo.size() != 1) {return null;}// Get component info and create ComponentNameResolveInfo serviceInfo = resolveInfo.get(0);String packageName = serviceInfo.serviceInfo.packageName;String className = serviceInfo.serviceInfo.name;ComponentName component = new ComponentName(packageName, className);// Create a new intent. Use the old one for extras and such reuseIntent explicitIntent = new Intent(implicitIntent);// Set the component to be explicitexplicitIntent.setComponent(component);return explicitIntent;}
}

这里用到了createExplicitFromImplicitIntent()方法是因为Android5.0中service的intent一定要显性声明,否则会报如下错误:

01-10 19:17:43.733 14662-14662/com.jason.aidl.client.aidlclient E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jason.aidl.client.aidlclient, PID: 14662
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jason.aidl.client.aidlclient/com.jason.aidl.client.aidlclient.MainActivity}: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.lyl.aidl }at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2381)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2443)at android.app.ActivityThread.access$800(ActivityThread.java:157)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5344)at java.lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.lyl.aidl }at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1781)at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1880)at android.app.ContextImpl.bindService(ContextImpl.java:1858)at android.content.ContextWrapper.bindService(ContextWrapper.java:539)at com.jason.aidl.client.aidlclient.MainActivity.onCreate(MainActivity.java:37)at android.app.Activity.performCreate(Activity.java:6033)at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2334)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2443) at android.app.ActivityThread.access$800(ActivityThread.java:157) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5344) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 

运行我们的Server端及Client端,在Client端的两个editText中输入两个数字点击按钮运行结果如下:

看见运行结果与我们预期一样,可见我们通过AIDL实现了App与App之间的远程调用。

以上只是一个简单的基本数据类型操作,那么我们怎么通过AIDL进行对象的操作呢,我们在之前代码上做些修改就行了,看下边吧。

我们在Server端与我们创建的.aidl同目录下创建一个Person.java的类与Person.aidl文件,目录结构如下

Person.java中成员变量包括一个name,一个age,ctrl+insert添加set与get方法,然后实现Parcelable接口序列化,里边有些方法需要自己实现Creator啊writeToParcel啊什么的,自己弄一下就行,两次ctrl+enter就行,然后自己写一个readFromParcel(Parcel dest)方法,要保证赋值顺序与writeToParcel中一致,否则会出问题。具体可以看下边代码:

package com.jason.aidl.aidldemo;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {private String name;private int age;public Person() {}protected Person(Parcel in) {name = in.readString();age = in.readInt();}public static final Creator<Person> CREATOR = new Creator<Person>() {@Overridepublic Person createFromParcel(Parcel in) {return new Person(in);}@Overridepublic Person[] newArray(int size) {return new Person[size];}};public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);dest.writeInt(age);}public void readFromParcel(Parcel dest) {name = dest.readString();age = dest.readInt();}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

Person.java完成了,看一下Person.aidl文件代码,很简单,如下:

// Person.aidl.aidl
package com.jason.aidl.aidldemo;
// Declare any non-default types here with import statements
parcelable Person;

就两行代码一个引入包,一个parcelable Person;这里注意前边的那个单词首字母是消协的,对,没错,相信自己的眼睛。

然后修改我们的IMyAidlInterface.aidl代码如下:

// IMyAidlInterface.aidl
package com.jason.aidl.aidldemo;// Declare any non-default types here with import statements
import com.jason.aidl.aidldemo.Person;
interface IMyAidlInterface {//处理基本类型;int add(int a,int b);//处理对象;String inPerson(in Person p);String outPerson(out Person p);String inOutPerson(inout Person p);
}

上面的代码中你需要手动引入Person类,因为在这里系统不会帮你引入,切记切记。还有你还会发现在方法的参数类型前有in、out、inout几个东西,不懂不要后边我们再分析。

Rebuild我们的项目你会发现报如下错误:

擦,为什么呢,因为AS是gradle构建项目的,如果不配置,它默认不会从aidl文件夹下寻找资源,所以我们需要在我们app下的build.gradle中添加如下配置:

sourceSets {main {java.srcDirs = ['src/main/java', 'src/main/aidl']}
}

之后在次rebuild就没问题了,运行后你会发现我们生成的.java文件中多了上边的几个刚刚操作对象的方法,代码就不粘了,太多了,都是系统生成的,本篇就不分析.java中的代码了,然后修改Service中的代码如下:

package com.jason.aidl.aidldemo;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;import com.jason.aidl.aidldemo.Person;public class MyAidlService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i("Log_LYL", "Onstart");return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {return stub;}IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {@Overridepublic int add(int a, int b) throws RemoteException {return a + b;}@Overridepublic String inPerson(Person p) throws RemoteException {String old = "name:" + p.getName() + " age:" + p.getAge();Log.d("Log_LYL:inPerson_", old);p.setName("李四");p.setAge(13);return "name:" + p.getName() + " age:" + p.getAge();}@Overridepublic String outPerson(Person p) throws RemoteException {String old = "name:" + p.getName() + " age:" + p.getAge();Log.d("Log_LYL:outPerson_", old);p.setName("周六");p.setAge(20);return "name:" + p.getName() + " age:" + p.getAge();}@Overridepublic String inOutPerson(Person p) throws RemoteException {String old = "name:" + p.getName() + " age:" + p.getAge();Log.d("Log_LYL:inOutPerson_", old);p.setName("弓七");p.setAge(57);return "name:" + p.getName() + " age:" + p.getAge();}};
}

到这里Server端的代码就算是修改完成了,然后把我们添加了Person.java与Person.aidl文件的整个文件夹copy覆盖掉我们Client端之前拷贝的包重新编译,rebuild项目,报错... 没改app下的build.gradle吧,改。然后修改我们Client端的MainActivity中的textView赋值的try catch代码块,如下:

try {int res = mService.add(a, b);Person p1 = new Person();p1.setName("刘大");p1.setAge(3);Person p2 = new Person();p2.setName("赵二");p2.setAge(3);Person p3 = new Person();p3.setName("张三");p3.setAge(3);tv.setText(res + "\n" + mService.inPerson(p1) + "\n" + mService.outPerson(p2) + "\n" + mService.inOutPerson(p3)+"\n" + p1.toString() + "\n" + p2.toString() + "\n" + p3.toString());} catch (RemoteException e) {e.printStackTrace();
}

然后运行Server端与Client端结果如下:

再看我们Server端服务中的打印信息:

我们通过Client端的显示与Server端的打印信息分析一下上边定义的时候的那个in、out、inout的作用,再看一下我们在.aidl中定义的三个方法:String inPerson(inPerson p);String outPerson(outPerson p);String inOutPerson(inoutPerson p);

先看第一个inPerson中定义的为in,从Client端我们在textView赋值中调用inPerson传入的Person值name为“刘大”,在服务端打印中可知我们在服务端顺利接收到了,然后我们将Person的name值改为“李四”,但是我们Client端的Person本身没有改变(通过UI中Person{name=’刘大’,age=3}可知)。

Client端调用outPerson()传入的p2对象在服务端没有接收到(通过01-10 20:24:11.038 6451-6478/com.jason.aidl.aidldemo D/Log_LYL:outPerson_: name:null age:0打印信息可知),但是服务端修改了p2我们在Client端收到了修改后的p2(通过Person{name=’周六’,age=20}可知)。

Client端调用inoutPerson()传入p3对象在服务端可以接收到修改后在Client端也能发现P3被修改了。

由以上三种情况可以知道in的作用是Client端给Server端传递数据,Server段修改修改数据对客户端没有影响;而参数为out时,Client端给服务端传的值服务端是收不到的,服务端可以修改Client端传递过去的值,会影响到Client端队形;最后inout就是二者的结合了,Client端传递的值Server端能够收到,Server端修改了数据,会影响Client端对象数据,他们是双向操作的。

到此关于AIDl前边的几个问题就都回答完了,总结一下我在编写过程中遇到的几个问题:

1.Client端在绑定Server端使用隐式方式时,要兼容Android5.0以上版本。

2.传递对象实现Parcelable接口时readFromParcel(Parcel dest)中获取变量值顺序要与writeFromParcel(Parcel dest)一致。

3.传递对象时,记得配置buidle.grable,两端都要配置。

好了,AIDL基础篇就到这里吧,希望对你有帮助,谢谢!最后附上代码下载地址:

http://download.csdn.net/detail/liuyonglei1314/9734165

Aidl更深入了解可以看我的另一篇博文:

http://blog.csdn.net/liuyonglei1314/article/details/54849197

Android进程间通讯AIDL使用及问题详解(雷惊风)相关推荐

  1. Android中进程间通讯 AIDL

    Android中进程间通讯 AIDL IDL Interface Description Language  接口描述语言 AIDL Android IDL 适用场景:    client进程必须是A ...

  2. 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制

    概述 最近在学习Binder机制,在网上查阅了大量的资料,也看了老罗的Binder系列的博客和Innost的深入理解Binder系列的博客,都是从底层开始讲的,全是C代码,虽然之前学过C和C++,然而 ...

  3. Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  4. Android(IPC)进程间通讯1:详解Binder由来?

    完整原文:http://tryenough.com/android-... Android开发的进程间通讯,整个Android的应用都依赖于binder做底层通信机制.而Linux中提供的进程间通讯方 ...

  5. Android-Binder进程间通讯机制-多图详解

    本系列: Android-Binder进程间通讯机制-多图详解 一次Binder通信最大可以传输多大的数据?​​​​​​​ 关于Binder (AIDL)的 oneway 机制 概述 最近在学习Bin ...

  6. 进程间通讯回调客户端

    首先进程间通讯的方式有:广播,ContentProvider(内容提供者),AIDL(Android接口定义语言) 今天我们所讲的就是AIDL: 首先定义AIDL接口文件,如果进程间要传递对象,那么这 ...

  7. 管道实现进程间通讯 、WaitNamedPipe

    一.管道实现进程间通讯 主要的理论知识 1.什么是管道以及分类 管道是两个头的东西,每一个头各连接一个进程或者同一个进程的不同代码,依照管道的类别分有两种管道,匿名的和命名的:依照管道的传输方向分也能 ...

  8. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  9. linux open 头文件_linux下通过共享内存和mmap实现进程间通讯

    前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...

  10. linux mmap实例_Linux下通过共享内存和mmap实现进程间通讯(含实例)

    前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...

最新文章

  1. 通过反射给属性赋值代码示例
  2. 计算机网络的含义是什么意思,互联网的基本含义是什么
  3. mysql INFORMATION_SCHEMA COLUMNS 解释
  4. Java 设置文件只读
  5. C++友元函数简单示例
  6. jq项目如何启服务_用小项目详解我们应该如何去构建我们的微服务
  7. 7月25日训练赛签到题HDU1257
  8. 触发器中的 Inserted表和Deleted表
  9. json 和 数组的区别
  10. Java多线程系列---“基础篇”13之 乐观锁与悲观锁
  11. 原生App VS 移动Web App
  12. 这个录屏神器好用哭了!
  13. Win11如何重置电脑 Win11重置电脑教程
  14. 测试2年6.5K,每天“911”,我的心酸经历只有我自己知道···
  15. 文件包含漏洞及漏洞利用
  16. 前端xlsx插件简单说明
  17. 【转】Python实现量化选股
  18. vue克隆v2ex网站随记
  19. 24段魔尺--小海龟图案
  20. 一般配置的服务器租用一个月多少钱?服务器能买断嘛?

热门文章

  1. CPAN下载安装pm包方法
  2. C++小系统——餐馆员工管理系统及餐馆点菜系统(一)
  3. Vue+elementUI走马灯实现界面3分钟无点击操作出现全屏banner
  4. 亚马逊AWS免费云服务实战
  5. 用html数据库搭建信息管理系统,数据库的建立和系统模块功能的实现.doc
  6. 杨百翰大学计算机科学专业,杨百翰大学研究生什么专业好
  7. 年近30,半失业状态:定制化,正在拖垮年轻人
  8. Photoshop基础教程一:界面及新建
  9. 乘云而上,易捷行云入选“2020中国企服行业独角兽TOP50”
  10. 关于VM虚拟机一启动就会使电脑重启的问题