jni調試3(線程調試env變數問題),jnienv

來源:互聯網
上載者:User

jni調試3(線程調試env變數問題),jnienv

jni層調試線程死機原因

一,導致死機原因:

  jni層中  線程函數中  只要添加調用env 的函數 ,,就會死機   二,解決方案第一我們應該理解:①(獨立性) JNIEnv 是一個與線程相關的變數,即線程A有一個 JNIEnv變數, 線程B也有一個JNIEnv變數,由於線程相關,所以A線程不能使用B線程的 JNIEnv 結構體變數。 那麼如何保證了每個線程JNIEnv的獨立性呢? 

一個java對象通過JNI調用DLL中一個send()函數向伺服器發送訊息,不等伺服器訊息到來就立即返回,同時把JNI介面的指標JNIEnv *env(虛擬機器環境指標),和jobject obj儲存在DLL中的變數裡.一段時間後,DLL中的訊息接收線程接收到伺服器發來的訊息,並試圖通過儲存過的env和obj來調用先前的java對象的方法(相當於JAVA回調方法)來處理此訊息此時程式會突然退出(崩潰).

即前台JAVA線程發送訊息,後台線程處理訊息,歸屬於兩個不同的線程,不能使用相同的JNIEnv變數,這裡可以利用一個機制: 利用全域的 JavaVM * 指標得到當前線程的 JNIEnv* 指標,與在C++中兩個線程使用TLS進行局部儲存類似的原理。


具體方法:

擷取全域的JavaVM變數:

/* Our VM */
JavaVM *g_vm;

env->GetJavaVM(&g_vm); //來擷取JavaVM指標.擷取了這個指標後,將該JavaVM儲存起來。(轉錄)

 

②(公用性) 先瞭解 TLS(thread-local storage)

線程是執行的單元,同一個進程內的多個線程共用了進程的地址空間,線程一般有自己的棧,但是如果想要實現某個全域變數在不同的線程之間取不同的值,而且不受影響。一種辦法是採用線程的同步機制,如對這個變數的讀寫之處加臨界區或者互斥量,但是這是以犧牲效率為代價的,能不能不加鎖呢?線程局部儲存就是幹這個的。


 解決以上兩個問題:1首先定義全域變數
namespace android{       static JavaVM* gJavaVM  = NULL;  //定義一個全域Java VM引用對象       static jobject gJavaObj = NULL; //定義一個全域Java object對象,對於java層的類對象
    ......

 2其次在調用某個線程的函數中定義:(保證線程在進程中資源的公用性,這兩句是把參數傳給所開線程)

JNIEXPORT void JNICALL Java_Test_setEnev(JNIEnv *env, jobject obj)  {      env->GetJavaVM(&gs_jvm); //儲存到全域變數中JVM       //直接賦值obj到DLL中的全域變數是不行的,應該調用以下函數:       gs_object=env->NewGlobalRef(obj);     HANDLE ht=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFun,0,NULL,NULL);  }

 

3線上程函數中 引用:  (保證線程函數 對應  env  和class)
void WINAPI ThreadFun(PVOID argv)//JNI中線程回調這個方法   {    JNIEnv *env;   gs_jvm->AttachCurrentThread((void **)&env, NULL);    //對應這幾句說白了就是從上面函數中把變數取出來在該線程中使用 jclass cls = env->GetObjectClass(gs_object);   //擷取JAVA線程中的全域對象 jfieldID fieldPtr = env->GetFieldID(cls,"value","I");   // 擷取JAVA對象   while(1)   {      Sleep(100);     //這裡改變JAVA對象的屬性值(回調JAVA)      env->SetIntField(gs_object,fieldPtr,(jint)gs_i++);    }  }

 三,我們在網上看到有些關於jni的程式資料用了(*env)->;

我們需要謹記:在linux下如果.c檔案中用 “env->” 編譯會找不到此結構,必須用“(*env)->”,或者改成.cpp檔案,以 c++的方式來編譯。

 

------------------------------------------------------------------------    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.