Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建向量管理的JNI线程[C+;+;]_Java_C++_Vector_Java Native Interface_Pthreads - Fatal编程技术网

Java 创建向量管理的JNI线程[C+;+;]

Java 创建向量管理的JNI线程[C+;+;],java,c++,vector,java-native-interface,pthreads,Java,C++,Vector,Java Native Interface,Pthreads,简言之,我一直在努力实现以下目标:我希望能够有效地管理大量数据(数以十亿计/它们不需要很长时间就能完成,但我正在创建阵列以高速处理,如果我不立即将数据传递给线程,阵列将变得非常大,从而导致错误)必要时将数据传递给JNI并需要存储在向量中的线程 我一直面临两个问题: 第一个问题是,如果我试图产生超过45个线程同时运行JNI,Java就会崩溃。如果它们不是同时运行,那么它可以正常工作,但是我从GC那里收到很多抱怨,说它没有获得足够的内存,这似乎不会影响任何事情 第二个问题是,如果我以目前的速度生成线

简言之,我一直在努力实现以下目标:我希望能够有效地管理大量数据(数以十亿计/它们不需要很长时间就能完成,但我正在创建阵列以高速处理,如果我不立即将数据传递给线程,阵列将变得非常大,从而导致错误)必要时将数据传递给JNI并需要存储在向量中的线程

我一直面临两个问题:

第一个问题是,如果我试图产生超过45个线程同时运行JNI,Java就会崩溃。如果它们不是同时运行,那么它可以正常工作,但是我从GC那里收到很多抱怨,说它没有获得足够的内存,这似乎不会影响任何事情

第二个问题是,如果我以目前的速度生成线程,我用来管理并随后加入它们的向量就会变得太大

因此,总而言之,我需要一种快速的方法来跟踪我正在创建的线程,而不牺牲任何时间

//g++ -std=c++11 -I/usr/lib/jvm/java-8-openjdk/include -I/usr/lib/jvm/java-8-openjdk/include/linux cpptest/Test.cpp -L/usr/lib/jvm/java-8-openjdk/jre/lib/amd64/server -ljvm -lpthread
#include <jni.h>
#include <iostream>
#include <thread>
#include <string.h>
#include <vector>
#include <chrono>
#include <mutex>
#include <fstream>
#include <algorithm>

jclass cls;
jmethodID mid;
JNIEnv* env;
JavaVM* jvm;
std::mutex m;

typedef struct {
    long seed;
    int chunkX;
    int chunkZ;
    int eyes;
} Stronghold;

void ThreadFunc(Stronghold strhld, std::ofstream *outfile) {
  jvm->AttachCurrentThread((void**)&env, NULL);
  jlongArray rt = (jlongArray)env->CallStaticLongMethod(cls, mid, (jlong)strhld.seed, (jint)strhld.chunkX, (jint)strhld.chunkZ, (jint)strhld.eyes);
  jsize size = env->GetArrayLength(rt);
  std::vector<long> rtVec(size);
  env->GetLongArrayRegion(rt, 0, size, &rtVec[0]);
    jvm->DetachCurrentThread();
    std::string write;
    m.lock();
  for(long &element : rtVec) {
        write = std::to_string(element) + "; ";
    *outfile << write;
  }
    *outfile << std::endl;
    m.unlock();
}

int main(int argc, char* argv[]) {
  std::ofstream outfile("./new.txt",std::ofstream::binary);
    std::vector<std::thread> threads;

  const int kNumOptions = 3;
  JavaVMOption options[kNumOptions] = {
    { const_cast<char*>("-Xmx512m"), NULL },
    { const_cast<char*>("-verbose:gc"), NULL },
    { const_cast<char*>("-Djava.class.path=/home/jewe37/Desktop/"), NULL }
  };

  JavaVMInitArgs vm_args;
  vm_args.version = JNI_VERSION_1_8;
  vm_args.options = options;
  vm_args.nOptions = sizeof(options) / sizeof(JavaVMOption);

  env = NULL;
  jvm = NULL;
  JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &vm_args);

  const char* kClassName = "Processor";
  cls = env->FindClass(kClassName);
  if (cls == NULL) {
    std::cerr << "FINDCLASS" << std::endl;
        return 1;
    }

  const char* kMethodName = "ProcessSeed";
  mid = env->GetStaticMethodID(cls, kMethodName, "(JIII)[J");
  if (mid == NULL) {
    std::cerr << "FINDMETHOD" << std::endl;
        return 1;
    }

  Stronghold strhld;

    for(int i = 0; i < std::stoi(argv[1]); i++) {
        strhld = {i, i*2, i*3, i*4};
        threads.emplace_back(ThreadFunc, strhld, &outfile);
        std::this_thread::sleep_for(std::chrono::microseconds(50));
    }

    std::cout << threads.size() << std::endl;

    for (std::thread &thread : threads) if (thread.joinable()) thread.join();

  jvm->DestroyJavaVM();

  outfile.close();
  return 0;
}
//g++-std=c++11-I/usr/lib/jvm/java-8-openjdk/include-I/usr/lib/jvm/jvm/java-8-openjdk/include/linux-cpptest/Test.cpp-L/usr/lib/jre/lib/amd64/server-ljvm-lpthread
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
jclass cls;
jmethodidemid;
JNIEnv*env;
JavaVM*jvm;
std::互斥m;
类型定义结构{
长种子;
int-chunkX;
int-chunkZ;
内视眼;
}据点;
void ThreadFunc(据点strhld,std::of stream*outfile){
jvm->AttachCurrentThread((void**)和env,NULL);
jlongArray rt=(jlongArray)env->CallStaticLongMethod(cls,mid,(jlong)strhld.seed,(jint)strhld.chunkX,(jint)strhld.chunkZ,(jint)strhld.eyes);
jsize size=env->GetArrayLength(rt);
标准::向量rtVec(大小);
env->getlongarayregion(rt、0、size和rtVec[0]);
jvm->DetachCurrentThread();
std::字符串写入;
m、 锁();
用于(长元素和元素:rtVec){
write=std::to_字符串(元素)+“;”;

*outfile您不能在线程之间共享JNIEnv。它必须是每个线程的JNIEnv。请将env设置为ThreadFunc()的本地。这个问题已经得到了彻底的回答。另外,在退出本机线程之前,不要忘记分离本机线程。

您可以始终使用互斥锁,这样可以确保仅通过单个线程访问JVM:


听起来你在寻找一个线程池。创建一个新的线程相对来说比较昂贵,而且你做的事情太多了。此外,拥有比执行资源更多的并发线程通常是没有帮助的,而且可能是有害的。无论如何,我看不到在f任务的实际执行。将它们放在一个有界队列中,这样无论哪个线程生成它们,当它走得太远时都会阻塞。这可能会有额外的好处,释放资源来运行实际的作业。@JohnBollinger拥有这么多线程似乎是处理其他组件输出的最佳选择每350us就有一次变异。不过我确实需要使用线程,因为我需要将其分离出来,以便让其余的继续进行。我将看看线程池是否能在我的特定情况下工作。向量增长如此之大表明任务的执行跟不上它们的生成。rem可能减少创建和连接线程的开销(通过使用线程池)将有助于解决这一问题,但如果这还不够,那么您就有一个更深层次的问题。@JeWe37不可能让10亿个线程同时运行(因为这将占用至少4TB的RAM)。与启动和停止一组线程不同,您应该保持固定数量(例如32个)的线程运行,并将工作分配给它们。