Android Framework中的线程Thread及它的threadLoop方法

本文深入探讨了Android Framework中线程Thread的实现,特别是threadLoop方法的作用。从Java线程创建到Linux下的C语言线程pthread,再到Android Framework中的特殊线程形式,分析了threadLoop如何启动和循环运行。通过AudioWatchDog和SurfaceFlinger的实例,揭示了threadLoop在Thread中的运行原理,以及当threadLoop返回false时线程如何结束。对于那些在源码中难以找到run()方法调用的位置,作者建议检查onFirstRef()方法。
摘要由CSDN通过智能技术生成

当初跟踪Camera的代码中的时候一直追到了HAL层,而在Framework中的代码看见了许许多多的Thread。它们普遍的特点就是有一个threadLoop方法。按照字面的意思应该是这个线程能够循环处理数据。对应我想到到了java上层中的HandlerThread,这个估计也差不多,但当时心里总有一个疙瘩,想弄清楚它为什么能够循环,还有它到底是怎么循环起来的?

Android中java世界的Thread

我们先来看看java是怎么创建一个线程的。这个是最舒服的,也是我最熟悉的。


new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
                ...
        }
}).start();

当然,你也可以在android中创建一个消息循环的HandlerThread

HandlerThread mThread = new HandlerThread("test");
mThread.start();
Handler mHandler = new Handler(mThread.getLooper()){

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
        }

};

上面中通过mHandler发送消息就可以在mThread中处理了,并且这个mThread不是UIThread,不会阻塞主线程。
HandlerThread是一个好东西,在源码中处处可见,希望对此不熟悉的新手及时去学习下它的用法。

Linux下c语言的Thread

java世界的Thread很方便,那么c呢?
Android基于linux所以,多线程编程也应该基于linux下的多线程。linux下的c语言用pthread。大家可以看这篇文章。
linux下C/C++,多线程pthread

我把里面的例子改良了一下
test.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

//线程函数
void *test(void *ptr)
{
    int i;
    for(i=0;i<8;i++)
    {
        printf("the pthread running ,count: %d\n",i);
        sleep(1); 
    }

}


int main(void)
{
    pthread_t pId;
    int i,ret;
    //创建子线程,线程id为pId
    ret = pthread_create(&pId,NULL,test,NULL);

    if(ret != 0)
    {
        printf("create pthread error!\n");
        exit(1);
    }

    for(i=0;i < 5;i++)
    {
        printf("main thread running ,count : %d\n",i);
        sleep(1);
    }

    printf("main thread will exit when pthread is over\n");
    //等待线程pId的完成
    pthread_join(pId,NULL);
    printf("main thread  exit\n");

    return 0;

}

然后编译

gcc -o test test.c -lpthread
./test

运行结果如下

main thread running ,count : 0
the pthread running ,count: 0
main thread running ,count : 1
the pthread running ,count: 1
main thread running ,count : 2
the pthread running ,count: 2
main thread running ,count : 3
the pthread running ,count: 3
main thread running ,count : 4
the pthread running ,count: 4
main thread will exit when pthread is over
the pthread running ,count: 5
the pthread running ,count: 6
the pthread running ,count: 7
main thread  exit

例子比较简单,主要是创建一个线程,然后主线程等待子线程运行完毕再退出。

Android Framework中的Thread

下面焦点回到文章的主题当中,我们来看看Framework中常用的Thread是个何种形态。
先看看活生生的例子。
在源码中搜索threadLoop,当然也可以搜索thread,然后随便挑选一个Thread子类进行研究。这里挑选
/frameworks/av/services/audioflinger/AudioWatchdog.h

#ifndef AUDIO_WATCHDOG_H
#define AUDIO_WATCHDOG_H

#include <time.h>
#include <utils/Thread.h>

namespace android {

......

class AudioWatchdog : public Thread {

public:
    AudioWatchdog(unsigned periodMs = 50) : Thread(false /*canCallJava*/), mPaused(false),
            mPeriodNs(periodMs * 1000000), mMaxCycleNs(mPeriodNs * 2),
            // mOldTs
            // mLogTs initialized below
            mOldTsValid(false), mUnderruns(0), mLogs(0), mDump(&mDummyDump)
        {
#define MIN_TIME_BETWEEN_LOGS_SEC 60
            // force an immediate log on first underrun
            mLogTs.tv_sec = MIN_TIME_BETWEEN_LOGS_SEC;
            mLogTs.tv_nsec = 0;
        }
    virtual         ~AudioWatchdog() { }

     // Do not call Thread::requestExitAndWait() without first calling requestExit().
    // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
    virtual void        requestExit();

    // FIXME merge API and implementation with AudioTrackThread
    void            pause();        // suspend thread from execution at next loop boundary
    void            resume();       // allow thread to execute, if not requested to exit

    // Where to store the dump, or NULL to not update
    void            setDump(AudioWatchdogDump* dump);

private:
    virtual bool    threadLoop();

    Mutex           mMyLock;        // Thread::mLock is private
    Condition       mMyCond;        // Thread::mThreadExitedCondition is private
    bool            mPaused;        // whether thread is currently paused

    ......
};

}   // namespace android

#endif  // AUDIO_WATCHDOG_H

我们可以看到AudioWatchDog确实是Thread的子类,那好,下面看实现。
/frameworks/av/services/audioflinger/AudioWatchdog.cpp

#define LOG_TAG "AudioWatchdog"
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

frank909

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值