2023-01-20 339
我正在尝试使这个简单的示例起作用:
import java.io.*;
public class Timer {
public static void main(String[] args) {
setTimer(new Runnable() {
public void run() {
System.out.println("tick");
}
},
1000 /* msecs */
);
while (true) ;
}
native public static void setTimer(Runnable r, int msecs);
static {
System.loadLibrary("timer");
}
}
代码很简单.使用SIGALRM和setitimer在JNI/C/Linux中进行程序setTimer.示例应打印 tick 每秒.
JNI库被编程为:
#include <signal.h>
#include <sys/time.h>
#include "Timer.h"
#include "error.h"
static JNIEnv *genv;
static jobject gobj;
void handler(int s) {
jclass cls = (*genv)->GetObjectClass(genv, gobj);
jmethodID mid = (*genv)->GetMethodID(genv, cls, "run", "()V");
(*genv)->CallVoidMethod(genv, gobj, mid);
}
JNIEXPORT void JNICALL Java_Timer_setTimer
(JNIEnv *env, jclass cls, jobject obj, jint msecs) {
struct sigaction sa;
struct itimerval it;
sa.sa_flags = SA_RESTART;
sigemptyset (&sa.sa_mask);
genv = env;
gobj = obj;
sa.sa_handler = handler;
it.it_interval.tv_sec = msecs/1000;
it.it_interval.tv_usec = (msecs%1000)*1000;
it.it_value = it.it_interval;
if (sigaction (SIGALRM/*PROF*/, &sa, NULL) == -1
|| setitimer (ITIMER_REAL/*PROF*/, &it, NULL) == -1)
SysError("setTimer: sigaction, setitimer: couldn't init timer");
}
我正在使用信号链库,以免信号干扰JVM:
LD_LIBRARY_PATH=. LD_PRELOAD=/usr/lib/jvm/java-6-openjdk/jre/lib/i386/libjsig.so java Timer
第一次使用消息启动JMV segfaults:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00e9531c, pid=5742, tid=3077924544
#
...
为什么?
问题是无效的GENV和GOBJ. genv和gobj在变量集和离开java_timer_settimer函数之间有效.您可以从当前的JVM中获得Env*,并将OBJ转到Global Ref.我定义了新变量:
static JavaVM *jvm = NULL;
static jobject callback = NULL;
在java_timer_settimer中:
/* find the current jvm */
(*env)->GetJavaVM(env, &jvm);
/* upgrade callback to global ref */
callback = (*env)->NewGlobalRef(env, obj);
在手柄中,使用JVM连接当前线程并调用回调:
void handler(int s) {
if(jvm == NULL)
return ;
if(callback == NULL)
return ;
JNIEnv *env = NULL;
jint res;
res = (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
if(res < 0)
{
fprintf(stderr, "Attach VM Thread failed\n");
return ;
}
jclass cls = (*env)->GetObjectClass(env, callback);
jmethodID mid = (*env)->GetMethodID(env, cls, "run", "()V");
(*env)->CallVoidMethod(env, callback, mid);
(*jvm)->DetachCurrentThread(jvm);
}
最后,我们使其可运行:
qrtt1@qrtt1-VirtualBox:/media/sf_VBoxSharedFolder/0Lab$ java -Djava.library.path=. -classpath bin Timer
tick Tue Jul 24 13:01:54 CST 2012
tick Tue Jul 24 13:01:55 CST 2012
tick Tue Jul 24 13:01:56 CST 2012
tick Tue Jul 24 13:01:57 CST 2012
tick Tue Jul 24 13:01:58 CST 2012
完成的源代码为:
#include "Timer.h" #include <jni.h> #include <signal.h> #include <sys/time.h> #include <stdio.h>static JavaVM *jvm = NULL; static jobject callback = NULL;
void handler(int s) { if(jvm == NULL) return ; if(callback == NULL) return ; JNIEnv *env = NULL; jint res; res = (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); if(res < 0) { fprintf(stderr, "Attach VM Thread failed\n"); return ; } jclass cls = (*env)->GetObjectClass(env, callback); jmethodID mid = (*env)->GetMethodID(env, cls, "run", "()V"); (*env)->CallVoidMethod(env, callback, mid); (*jvm)->DetachCurrentThread(jvm); }
/* * Class: Timer * Method: setTimer * Signature: (Ljava/lang/Runnable;I)V */ JNIEXPORT void JNICALL Java_Timer_setTimer (JNIEnv *env, jclass cls, jobject obj, jint msecs) { struct sigaction sa; struct itimerval it; sa.sa_flags = SA_RESTART; sigemptyset (&sa.sa_mask); /* find the current jvm */ (*env)->GetJavaVM(env, &jvm); /* upgrade callback to global ref */ callback = (*env)->NewGlobalRef(env, obj); sa.sa_handler = handler; it.it_interval.tv_sec = msecs/1000; it.it_interval.tv_usec = (msecs%1000)*1000; it.it_value = it.it_interval; if (sigaction (SIGALRM/*PROF*/, &sa, NULL) == -1 || setitimer (ITIMER_REAL/*PROF*/, &it, NULL) == -1) { // error. } }
以上所述是小编给大家介绍的使用JNI将java与C计时器库接口,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25944.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态