JNI回调时线程安全的处理
来源:互联网 发布:mac版围棋对弈软件 编辑:程序博客网 时间:2024/06/01 15:00
在网上能找到有关
“在Jni中通过 env->CallStaticVoidMethod去做callback的时候,总会挂掉 原因是JniEnv是和线程相关的,只能在对应创建的线程中使用 而JVM却是进程相关的,可以通过JVM来获取线程相关的JNIENV。”
关于这个的解决办法,能搜到的都基本一模一样。变量名都不带改的。
比如:http://blog.chinaunix.net/uid-21564437-id-3343209.html
http://my.oschina.net/u/97468/blog/383492
基本都是通过
fields.pjvm->AttachCurrentThread(&env, NULL); env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg); Fields.pjvm->DetachCurrentThread();
这种方式来解决线程问题。
今天偶然发现一种挺好的方式:
JNIEXPORT jint JNICALL Reset (JNIEnv *env, jclass cls){SET_ENV(env);.....} void SET_ENV(JNIEnv* env){pid_t tid = syscall(__NR_gettid); // current thread idg_JNIENV_Map[tid] = env;}
下面这部分是抄来的
//system call number:
#define __NR_gettid 224
因此,要获取某个线程的TID,最nasty的方式是:
1. #include <sys/syscall.h>
2. printf("The ID of this thread is: %ld\n", (long int)syscall(224));
或者比较elegant的方式是:
1. #include <sys/syscall.h>
2. #define gettidv1() syscall(__NR_gettid)
3. #define gettidv2() syscall(SYS_gettid)
4. printf("The ID of this thread is: %ld\n", (long int)gettidv1());// 最新的方式
5. printf("The ID of this thread is: %ld\n", (long int)gettidv2());// traditional form
PS: 在/usr/include/sys/syscall.h中可以看到关于__NR_<name>和SYS_<name>两个宏的区别,实际最后使用的都是__NR_<name>。
就是为了证明这代码是获取当前线程ID的(Linux)
pid_t tid = syscall(__NR_gettid); // current thread id
JNIEnv* GET_ENV(){pid_t tid = syscall(__NR_gettid); // current thread id map<pid_t, JNIEnv*>::iterator it = g_JNIENV_Map.find(tid);if (it == g_JNIENV_Map.end()){return NULL;}else{return it->second;}} 这样,你在需要使用env的时候就能根据当前线程找到对应的正确的env指针了。JNIEnv *env = GET_ENV();jclass cls = env->FindClass(XXX);jmethodID methodId = env->GetStaticMethodID(cls, "showDialog", "()V");
- JNI回调时线程安全的处理
- JNI的线程处理
- LinkedList的线程安全处理
- servlet的线程安全处理方式
- Android中Handler线程的处理是线程安全的
- Java处理线程同步/线程安全的方式概述
- 单例模式实现 线程安全的队列 处理
- javaweb--servlet--servlet的异常处理和线程安全简述
- 浅谈android的线程安全和handler处理
- JNI异常的处理
- JNI 多线程的处理
- JNI异常的处理
- JNI异常的处理
- jni的异常处理
- [Android] JNI 中传递字符串参数(String)的安全处理方式
- 线程安全非线程安全的区别
- JVMTI 中的JNI系列函数,线程安全及调试技巧
- java的线程安全
- Linux tty字符终端下VIM显示混乱的解决方法
- DDMS中File Explorer无法查看data/data文件解决办法
- 【OC易错】OC易出错的地方
- android:versionCode和android:versionName 用途
- 关于android尺寸单位换算
- JNI回调时线程安全的处理
- Swift函数的使用
- 2015-3-31 浏览器本地缓存问题
- 【C++基础之八】函数指针和回调函数
- uboot 读书笔记【1】
- 乌鲁木齐爱德华医院2015年全国第13个爱鼻日健康公益活动
- 中国银行支付接口(ecshop版)
- Arm Reference
- RabbitMQ消息队列(二):”Hello, World“(转)