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

一个Binder的前生今世 (二):Binder进程和线程的创建

文章目录

  • 一个Binder的前生今世 (二):Binder进程和线程的创建
    • binder在进程中的启动
    • 小结
    • 注释

一个Binder的前生今世 (二):Binder进程和线程的创建

前篇文章一个Binder的前生今世 (一):Service的创建 讲了一个Service是如何创建以及如何与客户端建立联系的。讲解中涉及到了两个类 ProcessStateIPCThreadState ,当时没有详细介绍这两个类是怎么来的,只是介绍了它们在Binder客户端和服务端传递的作用。这篇文章我们就来深入了解下这两个类以及和binder的关系。可以说这两个类整个串联起了Binder驱动和Binder应用的联系,在Binder的架构实现中属于中流砥柱的作用。

binder在进程中的启动

首先要明确一个概念: 一个进程中对应一个Binder进程(也就是后文说的ProcessState)用来管理与Binder驱动的通讯和Binder对应的应用线程(后文说的IPCThreadState)。

要说明Binder在进程中如何启动,我们就需要先了解一个android的应用是如何创建起来的。当然我们这篇文章不介绍Android应用是如何创建的,不了解的可以网上查看其他的资料,很多,我也会另写文章记录。

Android的应用都会通过app_main.cpp来创建,惯例,我们先来明确用到的类的路径:

app_main.cpp : Android/frameworks/base/cmds/app_process/app_main.cpp
IPCThreadState : Android/frameworks/native/libs/binder/IPCThreadState.cpp
ProcessState : Android/frameworks/native/libs/binder/ProcessState.cpp

好,我们了解到,Android应用的启动都会走到app_main.cpp中的AppRuntime类的onZygoteInit函数:

virtual void onZygoteInit()
    {
   
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

好,这里我们今天的第一个主角类登场了:ProcessState。先来了解下这个类。
这个类和IPCthreadState在Android的Binder架构体系中启动连接应用层和驱动层的作用,应用和驱动层打交道的所有接口调用都是在这两个类中的。
所以,每当一个应用初始化的时候,都会调用到这里,那我们就接着往下看这个ProcessState是如何初始化的:

sp<ProcessState> ProcessState::self()
{
   
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != nullptr) {
   
        return gProcess;
    }
    gProcess = new ProcessState(kDefaultDriver);
    return gProcess;
}

这个self函数就是一个单例模式,创建ProcessState

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mBinderContextCheckFunc(nullptr)
    , mBinderContextUserData(nullptr)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
   

// TODO(b/139016109): enforce in build system
#if defined(__ANDROID_APEX__)
    LOG_ALWAYS_FATAL("Cannot use libbinder in APEX (only system.img libbinder) since it is not stable.");
#endif

    if (mDriverFD >= 0) {
   
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
   
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

#ifdef __ANDROID__
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
#endif
}

这里可以大概看出这个类是管理一个线程池的作用,另外还有管理binder驱动,我们可以看到第3行open_driver ,这里就是打开了Bidner驱动:

static int open_driver(const char *driver)
{
   
    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
   
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) {
   
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        }
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
   
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
            close(fd);
            fd = -1;
        }
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) {
   
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
   
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}

这里除了open驱动外,还设置了最大线程数,这里DEFAULT_MAX_BINDER_THREADS为15:

#define DEFAULT_MAX_BINDER_THREADS 15

然后,我们在回过头继续看ProcessState构造函数,接着初始化了一个锁mThreadCountLock 1和 一个条件变量 mThreadCountDecrement 2,最后初始花了内存映射:

mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

这里可以看到一个进程的mVMStart 内存映射大小为:

#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)

好了,到这里ProcessState的初始化就完成了,它是一个线程池,管理进程中所有的Binder线程,它还负责进程的Binder驱动打开和初始化操作,然后就是开启了与Binder驱动的内存映射。

我们接着来看proc->startThreadPool()

void ProcessState::startThreadPool()
{
   
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
   
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

从名字可以看出这个方法的作用就是启动线程池了。我们继续往下跟踪:

void ProcessState::spawnPooledThread(bool isMain)
{
   
    if (mThreadPoolStarted) {
   
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

这里的作用就是启动一个Binder线程了,接着我们就来到了查看PoolThread是个什么东东:

class PoolThread : public Thread
{
   
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
   
    }

protected:
    virtual bool threadLoop()
    {
   
        IPCThreadState::self(

http://www.kler.cn/a/108204.html

相关文章:

  • 大模型时代,呼叫中心部门如何自建一套大模型在线客服?
  • Python提取PDF和DOCX中的文本、图片和表格
  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • Spring MVC 与 JSP 数据传输
  • K8资源之endpoint资源EP资源
  • 网站小程序app怎么查有没有备案?
  • 爬取抖音用户的个人基本信息
  • Latex报错 “Paragraph ended before \Gin@iii was complete“
  • 万字解析设计模式之工厂方法模式与简单工厂模式
  • 竞赛选题 深度学习图像修复算法 - opencv python 机器视觉
  • 4.5 final修饰符
  • hive使用中的参数优化与问题排查
  • Kafka KRaft模式探索
  • 【unity小技巧】unity排序问题的探究
  • 如何使用 Rask AI 进行视频本地化
  • 腾讯云和阿里云双11优惠大战,服务器价格相差1块钱?
  • laravel+vue2 element 一套项目级医院手术麻醉信息系统源码
  • python实现ModBusTCP协议的server
  • 【vtk学习笔记1】编译安装vtk9.2.6,运行官方例子
  • 如何在linux服务器上安装Anaconda与pytorch,以及pytorch卸载
  • TextureView和SurfaceView
  • 【Python 算法】信号处理通过陷波滤波器准确去除工频干扰
  • localhost知识
  • iMazing2024年最新许可证-iMazing许可证激活补丁
  • UE5实现相机水平矫正
  • 基于数字电路交通灯信号灯控制系统设计-单片机设计