Transferred from: http://blog.csdn.net/llping2011/article/details/9706599
The thread function created in our Linux system is:pthread_create(), in Android we encapsulate a thread for threads, which is actually called pthread_create ()
When we want to create a thread, we simply inherit from the thread class and implement the virtual function Thread_loop ().
frameworks/Base/include/utils/Threads.hclassThread:Virtual PublicRefbase { Public: //creates a thread object, but does not immediately start the threading functionThread (BOOLCancalljava =true); Virtual~Thread (); //start the thread function, call the Threadloop Virtualstatus_t Run (Const Char*name =0, int32_t prority =Priority_default, size_t stack=0); //request to exit this thread Virtual voidRequestexit (); Virtualstatus_t Readytorun (); //call Requestexit () to wait until this thread exitsstatus_t requestexitandwait (); //wait until the thread exits and returns immediately if not startedstatus_t join (); protected: //returns True if Requestexit () is called BOOLExitpending ()Const; Private: //This is the actual thread function, and the inheriting class must implement it,//returns True if it is called again, and returns false if the message exits Virtual BOOLThreadloop () =0; //Prohibit Assignmentthread&operator= (Constthread&); //The inner class, called by the run function, actually calls Threadloop Static int_threadloop (void*user); Const BOOLMcancalljava; thread_id_t Mthread; //thread_id_t is actually a void* type .mutable Mutex MLock; Condition mthreadexitedcondition; status_t Mstatus; //Note: So the place to operate both variables needs to be locked. volatile BOOLmexitpending; volatile BOOLmrunning; SP<Thread>mholdself; };
Let's start by looking at the constructor of the thread class:
Thread::thread (bool Cancalljava) : Mcancalljava (Cancalljava), Mthread (thread_id_t ( -1)), MLock ("thrad::mlock"), mstatus (no_ ERROR), mexitpending (false), Mrunnig (false) {}
Functions that actually start the thread:
status_t Thread::run (Const Char*name, int32_t priority, size_t stack) {Mutex::autolock _l (mLock); if(Mrunnig)returninvalid_operation; Mstate=No_error; Mexitpending=false; Mthread= thread_id_t (-1); Mholdself= This;//holds a reference to the current objectMrunning =true; if(Mcancalljava) Res= Createthreadetc (_threadloop, This, name, priority, Stack, &mthread); ElseRes= Androidcreaterawthreadetc (_threadloop, This, name, priority, Stack,&mthread); if(res = =false) {Mstatus=Unknown_error; Mrunning=false; Mthread= thread_id_t (-1); Mholdself.clear (); returnUnknown_error; } returnNo_error; There's a judgment here. What's a Mcancalljava? Then look down at the inlineBOOLCreatethreadetc (thread_func_t entryfunction,void*UserData,Const Char* ThreadName ="Android:unnamed_thread", int32_t threadpriority=Priority_default, size_t threadstacksize=0, thread_id_t*threadid =0) { returnandroidcreatethreadetc (entryfunction, UserData, ThreadName, ThreadPriority, Threadstacksize, ThreadId) /c1>?true:false; } intandroidcreatethreadetc (thread_func_t entryfunction,void*UserData,Const Char*threadname, int32_t threadpriority=Priority_default, size_t threadstacksize=0, thread_id_t*threadid =0) { returnGCREATETHREADFN (entryfunction, UserData, ThreadName, ThreadPriority, Threadstacksize, threadId); }
We see that the last call is the GCREATETHREADFN function, and GCREATETHREADFN is a global function pointer,
static ANDROID_CREATE_THREAD_FN GCREATETHREADFN = Androidcreaterawthreadetc;
By default, it is assigned to ANDROIDCREATERAWTHREADETC, which is the same as the previous call???
Since it is a function pointer there must be a place for it to assign a value:
void Androidsetcreatethreadfunc (android_create_thread_fn func) { = func; }
Where does this function call? And what value does it give?
We found a place to start the virtual machine in the Androidruntime class:
int Androidruntime::startreg (jnienv* env) { Androidsetcreatethreadfunc (android_create_ THREAD_FN) javacreatethreadetc); return 0 ; }
So if our Mcancalljava is true, the call is:
intandroidruntime::javacreatethreadetc (android_thread_func_t entryfunction,void*UserData,Const Char*ThreadName, int32_t threadpriority, suze_t threadstacksize, android_thread_id_t*threadId) { void* * args = (void* *) malloc (3*sizeof(void*)); args[0] = (void*) entryfunction; args[1] =UserData; args[2] = (void*) StrDup (threadname); returnandroidcreaterawthreadetc (Androidruntime::javathreadshell, args. ThreadName, ThreadPriority, Threadstacksize, threadId); }
The last call or the same function that created the thread is not the same as the callback function, which becomes Androidruntime::javathreadshell
intANDROIDRUNTIME::JAVACREATETHREADETC (void*args) {Voir* Start = ((void* *) args) [0]; Voir* UserData = ((void* *) args) [1]; Voir* Name = ((void* *) args) [2]; Free (args); JNIEnv*env; Javaattachthread (Name,&env); Result= (*(android_thead_func_t) Start) (UserData); Javadetachthread (); Free (name); returnresult; }
Here the thread function Javathreadshell inside or call the previous _threadloop function, but before calling, call
Javaattachthread () Attach the thread into the JNI environment so that the thread function can invoke the JNI function and the last thread
The function exits and then calls Javadetachthread () to exit the JNI environment.
Now enter the thread function _threadloop (), which is a static function
intThread::_threadloop (void*user) {Thread*ConstSelf = static_cast<thread*>(user); SP<Thead> Strong (self->mholdself); WP<Thead>weak (strong); Self-mholdself.clear (); BOOLFirst =true; Do{//Enter a loop that determines whether to exit the thread by judging the return value and the internal exit flag bit BOOLresult; if(FISR) { First=false; Self->mstatus = self->Readytorun (); Result= (Self->mstatus = =no_error); if(Result &&!self->exitpendind ()) {//check whether to exitresult = Self->threadloop ();//calling the actual thread function } } Else{result= self->Threadloop (); } {Mutex::autolock _l ( self-MLock); if(Result = =false|| Self->mexitpending) { Self->mexitpending =true; Self-mrunning =false; Self->mthread = thread_ir_t (-1); Self-Mthreadexitedcondition.broadcast (); Break; }} strong.clear (); Strong=Weak.promote (); } while(Strong! =0); return 0; }
Here the conditions for the thread exit are:
1) result = True means that the subclass returns false in the implemented Threadloop function, so that the thread exits the
2) Mexidpendding = True This variable value is set by the Requestexit function of the thread class so that the thread exits passively.
Finally, if the thread exits, it needs to do some initialization, set the thread's running state, and broadcast the other objects that care about the thread.
Finally, if we want to use the threading class: 1 ) Create a class such as Mythread, inheriting with the Thead class 2 Implement the pure virtual function Threadloop of the parent class in the Mythread class, which is the thread function that we passed in when we called Pthread_create. 3
The thread class analysis of Android Development (reproduced)