我的本机C代码中存在段错误。
我的程序中有一个包含4thread的线程池,每个都执行一个新的MyObject() 在MyObject中我有
public class MyObject{
private final float[] pmt = new float[50];
private final float[] cond = new float[10];
private final float[][] don = new float[3][200000];
private final float[][] abaque = new float[2][100];
private final double[][] res = new double[3][200000];
private native int trade_OM(float[] pmt, float[][] abaque, float[][] don, float[] cond, double[][] res, int[] flag);
protected void callNative() {
trade_OM(pmt, abaque, don, cond, res, flag);
}
static {
System.loadLibrary("myDLL");
}
}
当一个线程空闲时,如果另一个任务到达,则该线程再次执行一个新的MyObject()并调用本机方法。
在新的MyObject()调用6或7后,我有一个段错误。
**在solaris上我使用truss **:
/16: lwp_sigmask(SIG_SETMASK, 0xFFBFFEFF, 0x0000FFF7) = 0xFFBFFEFF [0x0000FFFF]
/15: time() = 1398686601
/17: llseek(11, 0, SEEK_CUR) = 5887547
/15: open("Trade.log", O_RDWR|O_APPEND|O_CREAT, 0666) = 8
/17: llseek(11, 0, SEEK_CUR) = 5887547
/15: fstat64(8, 0xACFFD5B0) = 0
/17: close(11) = 0
/15: fstat64(8, 0xACFFD458) = 0
/17: time() = 1398686601
/15: ioctl(8, TCGETA, 0xACFFD53C) Err#25 ENOTTY
/18: Incurred fault #6, FLTBOUNDS %pc = 0xFE27E498
/18: siginfo: SIGSEGV SEGV_MAPERR addr=0x8682F278
/15: write(8, " 1 3 : 0 3 : 2 1 - 1".., 43) = 43
/18: Received signal #11, SIGSEGV [caught]
/18: siginfo: SIGSEGV SEGV_MAPERR addr=0x8682F278
/15: lseek(8, 0, SEEK_END) = 5887590
/17: open("Trade.log", O_RDWR|O_APPEND|O_CREAT, 0666) = 9
/15: llseek(8, 0, SEEK_CUR) = 5887590
/17: fstat64(9, 0xAB7FD4B0) = 0
/15: llseek(8, 0, SEEK_CUR) = 5887590
我需要同步C代码吗?或用C做线程?
我尝试使用(* env) - > MonitorEnter和(* env) - > MonitorExit但同样的问题。
如果我只使用一个线程启动相同的程序,我没有问题,没有内存泄漏。
这是C代码:
#include <stdio.h>
#include <stdlib.h>
#include "CTrade.h"
#include "../trace.h"
#include "../commun.h"
JNIEXPORT jint JNICALL Java_fr_edf_mpv2_serveurcalcul_castor_transverse_traitement_transformation_courbe_TrtNRC_trade_1OM
(JNIEnv *env, jobject obj, jfloatArray pmtPar, jobjectArray abqPar, jobjectArray donPar, jfloatArray condPar, jobjectArray resPar, jintArray flagPar)
{
float ** don0 = NULL ; // Pour pouvoir desallouer les elements Java
float ** abq0 = NULL ; // Pour pouvoir desallouer les elements Java
int err = 0 ;
jfloat *pmt;// [SIZE_PMT] ; //parametres
jfloat * abq ;//[SIZE_ABQ_2][SIZE_ABQ_1] ; // abaques
jfloat *cond;//[SIZE_COND] ; //Conditions
jfloat * don ;//[SIZE_DON_2][SIZE_DON_1] ; // Donnees
jfloat * res ;//[SIZE_RES_2][SIZE_RES_1] ; // Resultats
int *flag ; //[SIZE_FLAG] ; // Retour Erreur
int iFlag=0 ;
SetLogFileName("Trade.log") ;
ZTrace(" On est dans Trade.c");
//
// Init parametre : pmt
//
if((err = GetTableauFloat("pmt", env, pmtPar, & pmt))== 0)
{
//
// Init parametre : abq
//
if((err = GetMatriceFloat("abq", env, abqPar, & abq0, & abq)) == 0)
{
//
// Init parametre : cond
//
if((err = GetTableauFloat("cond", env, condPar, & cond)) == 0)
{
//
// Init parametre : don
//
if((err = GetMatriceFloat("don", env, donPar, & don0, & don)) == 0)
{
//
// Allocation du tableau resultat
//
ZTrace("Allocation res") ;
if((err = AllocationMatriceFloat("res", env, resPar, & res)) == 0)
{
//
// Allocation du tableau flag
//
if((err = AllocationTableauInt("flag", env, flagPar, & flag)) == 0)
{
//here i have a Fortran Call that i remove because problem exist without this call
if((err = TransfertTableauInt("flag", env, flagPar, flag)) == 0)
{
if((err = TransfertMatriceFloat("res", env, resPar, res)) == 0)
{
}
}
ZTrace("Libere Flag") ;
free(flag) ;
}
ZTrace("Libere res") ;
free(res) ;
}
ZTrace("Libere don");
free(don) ;
if(don0)
FreeMatriceFloat(env, donPar, don0) ;
}
(*env)->ReleaseFloatArrayElements(env, condPar, cond, JNI_ABORT) ;
}
ZTrace("Libere abq");
free(abq);
if(abq0)
FreeMatriceFloat(env, abqPar, abq0) ;
}
(*env)->ReleaseFloatArrayElements(env, pmtPar, pmt, JNI_ABORT) ;
}
return err;
}
Trace.c仅用于创建文件的封装方法并在其中写入
commun.c包含分配数组的方法
int GetMatriceFloat(LPCSTR nomTab, JNIEnv *env, jobjectArray donPar, float * ** don, float ** donFor)
{
int ind, jnd, sizeDon, sizeDon1 ;
sizeDon = (*env)->GetArrayLength(env, donPar);
ZTrace("Size %s = %d", nomTab, sizeDon) ;
if((* don = (jfloat **)calloc(sizeDon, sizeof(jfloat *))))
{
//
// Init matrice don
//
for(ind = 0 ; ind < sizeDon ; ind ++)
{
jfloatArray donPari = (jfloatArray) (*env)->GetObjectArrayElement(env, donPar, ind);
sizeDon1 = (*env)->GetArrayLength(env, donPari);
ZTrace("Size1 %s = %d", nomTab, sizeDon1) ;
(* don)[ind] = (jfloat *) (*env)->GetFloatArrayElements(env, donPari, NULL);
if((* don)[ind] == NULL)
{
ZTrace("Erreur -23") ;
return -23;/* exception occurred */
}
}
if((* donFor = calloc(sizeDon1 * sizeDon, sizeof(float))) == NULL)
{
ZTrace("Erreur -22") ;
return -22 ;
}
for(ind = 0 ; ind < sizeDon ; ind ++)
{
for(jnd = 0 ; jnd < sizeDon1 ; jnd ++)
{
* (* donFor + jnd * sizeDon + ind) = (* don)[ind][jnd] ;
if((* don)[ind][jnd] != 0.0)
ZTrace("%s[%d][%d] = %g", nomTab, jnd, ind, (* don)[ind][jnd]) ;
}
}
//free(don) ;
return 0 ;
}
else
{
ZTrace("Erreur -24") ;
return -24 ;
}
}
int FreeMatriceFloat(JNIEnv *env, jobjectArray donPar, float ** don)
{
int ind, sizeDon ;
sizeDon = (*env)->GetArrayLength(env, donPar);
for(ind = 0 ; ind < sizeDon ; ind ++)
{
jfloatArray donPari = (jfloatArray) (*env)->GetObjectArrayElement(env, donPar, ind);
(*env)->ReleaseFloatArrayElements(env, donPari, don[ind], JNI_ABORT);
}
free(don) ;
}
如果你在getmatricefloat或其他东西的调用中看到某些内容让我知道;)如果不是我可以发布其他函数TransfertMatriceFloat / AllocationMatriceFloat / TransfertMatriceInt等...以查看问题是否在其中
感谢提前
答案 0 :(得分:0)
调用任何非线程安全的代码都有可能导致无法预料的问题 您的症状和旁路修复大声尖叫您的本机代码不是 线程安全的。
在你的情况下,因为你肯定知道100ms延迟阻止了 操作系统看到分段违规,至少应该
remove the delay
并更改
private native int myMethod(float[][] test, float[] tutu);
到
synchronized private native int myMethod(float[][] test, float[] tutu);
防止并发执行您的本机代码。