国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

jni調試3(線程調試env變量問題)

2024-06-28 13:19:25
字體:
來源:轉載
供稿:網友
jni調試3(線程調試env變量問題)

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++的方式來編譯。

------------------------------------------------------------------------
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 无为县| 隆安县| 沁阳市| 松潘县| 墨玉县| 承德市| 永善县| 浙江省| 鲁山县| 甘泉县| 临清市| 柳河县| 惠来县| 苍溪县| 东阳市| 阿巴嘎旗| 罗源县| 博客| 桐梓县| 仪征市| 兴隆县| 临邑县| 钦州市| 平安县| 苏尼特右旗| 临潭县| 宁波市| 黑龙江省| 綦江县| 哈尔滨市| 广汉市| 类乌齐县| 巴马| 云南省| 调兵山市| 明水县| 高唐县| 溆浦县| 靖州| 南江县| 沐川县|