java - शहर - यूपी के जिला फर्रुखाबाद की ताजा जानकारी



आप जेएनआई पर्यावरण के मूल पक्ष पर थ्रेड को कैसे ठीक से सिंक्रनाइज़ करते हैं? (1)

यदि दोनों थ्रेड JVM से जुड़े होते हैं, तो आप JNIEnv के MonitorEnter(jobject) और MonitorExit(jobject) फ़ंक्शन के माध्यम से JNIEnv के सिंक्रनाइज़ेशन तक पहुंच सकते हैं। जैसे ही यह लगता है, MonitorEnter प्रदान किए गए jobject पर ताला jobject , और MonitorExit की गई प्रदान की गई jobject पर लॉक जारी करता है।

नोट: इसके बारे में जागरूक होने के लिए कुछ नुकसान हैं! MonitorEnter के विवरण के अंतिम अनुच्छेद और MonitorExit विवरण के अंतिम पैराग्राफ को MonitorExit MonitorEnter / MonitorExit के बारे में दूसरे समान तंत्रों के साथ देखें, जिन्हें आप अन्यथा सोच सकते हैं।

यहां देखें

MonitorEnter

जीनट मॉनिटरएन्टर (जेएनआईइएनव * एनवी, जॉबकेड ओजेजी);

Obj द्वारा निर्दिष्ट अंतर्निहित जावा ऑब्जेक्ट से जुड़े मॉनिटर में प्रवेश करती है। Obj द्वारा निर्दिष्ट ऑब्जेक्ट के साथ जुड़े मॉनिटर में प्रवेश करती है Obj संदर्भ नल नहीं होना चाहिए प्रत्येक जावा ऑब्जेक्ट में इसके साथ जुड़े एक मॉनिटर है। अगर वर्तमान धागा पहले से ओबोज से जुड़े मॉनिटर का मालिक है, तो यह मॉनिटर में एक काउंटर को बढ़ाता है, जो इस थ्रेड ने मॉनिटर में दर्ज किए गए समय की संख्या को दर्शाता है। अगर obj से जुड़े मॉनिटर किसी भी थ्रेड के स्वामित्व में नहीं है, तो मौजूदा थ्रेड मॉनिटर के मालिक बन जाता है, इस मॉनीटर की प्रविष्टि संख्या 1 पर सेट करता है। ओबीजे से जुड़े मॉनिटर का कोई दूसरा धागा पहले से ही है, तो वर्तमान थ्रेड तक इंतजार करता है मॉनिटर जारी किया जाता है, फिर स्वामित्व हासिल करने के लिए फिर से कोशिश करता है।

मॉनिटरएन्टर जेएनआई फ़ंक्शन कॉल के माध्यम से दर्ज एक मॉनिटर को मॉनिटेरेक्सिट जावा वर्चुअल मशीन निर्देश या सिंक्रनाइज़ किए गए विधि रिटर्न के उपयोग से बाहर नहीं किया जा सकता है। एक मॉनिटर एंटर JNI फ़ंक्शन कॉल और एक मॉनिटर मॉर्निंग जावा वर्चुअल मशीन निर्देश एक ही ऑब्जेक्ट से जुड़े मॉनिटर को दर्ज करने की दौड़ में हो सकता है।

डेडलॉक से बचने के लिए, मॉनिटरएन्टर जेएनआई फंक्शन कॉल के जरिए मॉनिटर मॉनिटरएक्सिट जेएनआई कॉल का इस्तेमाल किया जाना चाहिए, जब तक DetachCurrentThread कॉल को जेएनआई मॉनिटर रिलीज़ करने के लिए उपयोग नहीं किया जाता है।

LINKAGE :

JNIEnv इंटरफ़ेस फ़ंक्शन तालिका में अनुक्रमणिका 217।

पैरामीटर :

env: जेएनआई इंटरफ़ेस पॉइंटर

obj: एक सामान्य जावा ऑब्जेक्ट या क्लास ऑब्जेक्ट

रिटर्न :

सफलता पर "0" देता है; विफलता पर नकारात्मक मान देता है

तथा

MonitorExit

जीनट मॉनिटरएक्सिट (जेएनआईइएनव * एनवी, जॉजेक्ट ओबीजे);

वर्तमान थ्रेड ओबीजे द्वारा निर्दिष्ट अन्तर्राष्ट्रीय जावा ऑब्जेक्ट से जुड़े मॉनिटर के मालिक होने चाहिए। धागा काउंटर को इस मॉनिटर में दर्ज किए गए समय की संख्या को इंगित करता है। यदि काउंटर का मान शून्य हो जाता है, तो वर्तमान धागा मॉनिटर को रिलीज़ करता है।

नेटिक्ट कोड को मॉनिटरएक्सिट का उपयोग किसी सिंक्रनाइज़ विधि या मॉनिटरनटर जावा आभासी मशीन अनुदेश के माध्यम से दर्ज मॉनिटर से बाहर निकलने के लिए नहीं करना चाहिए।

LINKAGE :

JNIEnv इंटरफ़ेस फ़ंक्शन तालिका में इंडेक्स 218।

पैरामीटर :

env: जेएनआई इंटरफ़ेस पॉइंटर

obj: एक सामान्य जावा ऑब्जेक्ट या क्लास ऑब्जेक्ट

रिटर्न :

सफलता पर "0" देता है; विफलता पर नकारात्मक मान देता है

अपवाद :

IllegalMonitorStateException: अगर मौजूदा थ्रेड मॉनिटर के पास नहीं है I

इसलिए प्रश्न में सी ++ कोड जो pthreads का उपयोग करने का प्रयास किया, उसे निम्नलिखित के रूप में परिवर्तित किया जाना चाहिए (कोड मानता है कि JNIEnv* पॉइंटर को किसी खास तरह से पहले JNIEnv* फैशन में अधिग्रहण किया गया था):

class objectA
{
    jobject dataMutex;
    ... // everything else mentioned before
}

// called on c++ thread
void objectA :: poll()
{
    // You will need to aquire jniEnv pointer somehow just as usual for JNI
    jniEnv->MonitorEnter(dataMutex);

    ... // all the poll stuff from before

    jniEnv->MonitorExit(dataMutex);
}

// called on java thread
void objectA :: supplyData(JNIEnv* jni, jobject jthis, jobject data)
{
    // You will need to aquire jniEnv pointer somehow just as usual for JNI
    jniEnv->MonitorEnter(dataMutex);

    ... // all the supplyData stuff from before

    jniEnv->MonitorExit(dataMutex);
}

कुडोस @ आरडीओडीएफ ने जवाब दिया था। दुर्भाग्य से यह एक टिप्पणी के रूप में था। मैं अगले दिन दोपहर तक इंतजार कर रहा था ताकि रेडिओफ़ेड के जवाब देने के लिए समय की अनुमति मिल सके, इसलिए अब मैं यह कर रहा हूं। मैं इस को ठीक करने के लिए की जरूरत कुहनी से छुटकारा प्रदान करने के लिए धन्यवाद Radiodef।

प्रश्न संक्षिप्त

मैं जेएनआई के माध्यम से एक प्रक्रिया में सी ++ और जावा का उपयोग कर रहा हूं। प्रश्न के उपयोग केस के लिए, दोनों सी ++ थ्रेड और जावा थ्रेड एक ही डेटा तक पहुंच रहे हैं, वे सी + + पक्ष पर ऐसा कर रहे हैं, और मैं एक्सेस ठीक से सिंक्रनाइज़ करना चाहता हूं।

अब तक, लगभग सभी मेरे जेएनआई धागा सिंक्रनाइज़ेशन जावा की तरफ जहां उत्तर स्पष्ट है: प्रदान की गई जावा संगामिति पैकेज और अंतर्निर्मित संगामिति भाषा सुविधाओं का उपयोग करें। दुर्भाग्य से, जवाब सी + + पक्ष पर इतना स्पष्ट नहीं है

क्या मैंने अभी तक कोशिश की है संक्षिप्त

मुझे लगता है कि यह थ्रेड बनाने के लिए pthreads का उपयोग नहीं कर रहा है, हालांकि यह काम कर सकता है सोचने के लिए एक pthreads mutex का उपयोग करने की कोशिश की, लेकिन कभी कभी ताला लगाने की कोशिश कर रहा है जब मैं अटक जाता है - मैं नीचे कि नीचे का उदाहरण दिखाएगा

प्रश्न का विवरण

मेरे वर्तमान, विशिष्ट उपयोग में, सी ++ 1 सेकंड टाइमर पर जावा द्वारा प्रदान किए गए बदलावों के लिए मतदान करना है (न कि मैं क्या चाहता हूं, लेकिन मुझे यकीन नहीं है कि मैं इसे कैसे बनाऊँगा, जो कि विरासत सी ++ कोड की प्रकृति )। जावा धागा एक देशी फ़ंक्शन को कॉल करके डेटा प्रदान करता है और सी ++ डेटा को सी ++ संरचना में कॉपी करता है

यह कोड की स्थिति का प्रकार है (2 धागे, थ्रेड 1 और थ्रेड 2 पर होता है):

कोड उदाहरण

काफी SSCCE को नोट करें, क्योंकि यह TheData और TheDataWrapper लिए परिभाषाओं को याद नहीं कर रहा है, लेकिन यह वास्तव में क्या मायने रखता है जो उनके पास नहीं है। मान लीजिए कि वे केवल कुछ सार्वजनिक int को शामिल करते हैं, अगर आपकी सोच प्रक्रिया में मदद मिलती है (हालांकि, मेरे मामले में, यह वास्तव में इंट और एंटर फ्लैप के कई सरणियों का है)।

सी ++:

class objectA
{
    void poll();
    void supplyData(JNIEnv* jni, jobject jthis, jobject data);
    TheDataWrapper cpp_data;
    bool isUpdated;

    void doStuff(TheDataWrapper* data);
};

// poll() happens on a c++ thread we will call Thread1
void objectA :: poll()
{
    // Here, both isUpdated and cpp_data need synchronization

    if(isUpdated)
    {
        do_stuff(&cpp_data);
        isUpdated = false;
    }
}

// supplyData happens on the Thread2, called as a native function from a java thread
void objectA :: supplyData(JNIEnv* jni, jobject jthis, jobject data)
{
    // some operation happens that copies the java data into a c++ equivalent
    // in my specific case this happens to be copying ints/floats from java arrays to c++ arrays
    // this needs to be synchronized
    cpp_data.copyFrom(data);
    isUpdated = true;
}

जावा:

class ObjectB
{
    // f() happens on a Java thread which we will call Thread2
    public void f()
    {
        // for the general case it doesn't really matter what the data is
        TheData data = TheData.prepareData();
        supplyData(data);
    }

    public native void supplyData(TheData data);
}

क्या मैंने अभी तक कोशिश की है विवरण

जब मैंने नीचे दिए गए pthread के लॉकिंग की कोशिश की, कभी-कभी निष्पादन pthread_mutex_lock में फंस जाता है। इस परिस्थिति में एक गतिरोध नहीं होना चाहिए, लेकिन सिर्फ आगे की जांच करने के लिए मैं एक परिदृश्य चलाया जहां आपूर्ति डेटा को supplyData भी नहीं बुलाया गया था (कोई डेटा नहीं दिया जा रहा था), इसलिए कोई गतिरोध संभव नहीं हो सकता था, फिर भी poll लिए पहली कॉल कभी-कभी लटका भी। शायद इस स्थिति में एक pthreads mutex का उपयोग करना एक अच्छा विचार नहीं है? या शायद मैंने कुछ बेवकूफ किया और इसे अनदेखा करते रहें।

अब तक, मैंने नीचे दिए गए pthreads का उपयोग करने की कोशिश की:

कोड उदाहरण

सी ++:

class objectA
{
    pthread_mutex_t dataMutex;
    ... // everything else mentioned before
}

// called on c++ thread
void objectA :: poll()
{
    pthread_mutex_lock(&dataMutex);

    ... // all the poll stuff from before

    pthread_mutex_unlock(&dataMutex);
}

// called on java thread
void objectA :: supplyData(JNIEnv* jni, jobject jthis, jobject data)
{
    pthread_mutex_lock(&dataMutex);

    ... // all the supplyData stuff from before

    pthread_mutex_unlock(&dataMutex);
}

मैंने एक दूसरे विकल्प के बारे में सोचा, लेकिन मैंने ऐसा नहीं किया है

मैंने जावा की संगामिति नियंत्रण का उपयोग करके लॉक का अनुरोध करने के लिए जावा में वापस कॉल करने के लिए जेएनआई का उपयोग करने पर भी विचार किया। यह काम करना चाहिए, जैसा कि थ्रेड को जवा पक्ष पर आवश्यक रूप से ब्लॉक करना चाहिए। हालांकि, सी ++ से जावा तक पहुंचने के बाद से यह अत्यधिक सिरदर्द है, मैं उस सिरदर्द से गुज़रने से बचने की उम्मीद कर रहा था। मैं शायद एक सी + + क्लास बना सकता हूं जो जेएनआई कॉल को जावा लॉक के लिए अनुरोध करने के लिए कॉल करता है; जो सी ++ कोड को आसान बनाते हैं, यद्यपि मुझे लगता है कि जेएनआई पर सिर्फ धागा ताले के लिए आगे और आगे पार करने के ऊपरी हिस्से के बारे में

ऐसा लगता है कि @Radiodef द्वारा टिप्पणी के अनुसार यह आवश्यक नहीं है ऐसा प्रतीत होता है कि MonitorEnter में MonitorEnter / MonitorExit फ़ंक्शन शामिल हैं जो पहले से ही सी ++ पक्ष पर लॉकिंग को संभालते हैं। जावा साइड पर परंपरागत ताले के रूप में एक ही समय में इनका उपयोग करते समय नुकसान होते हैं, इसलिए कृपया उपयोग करने से पहले यहां पढ़ें । मैं यह कोशिश कर रहा हूं, और मुझे उम्मीद है कि MonitorEnter / MonitorExit का जवाब होगा और मैं सुझाता हूं @ Radiodef टिप्पणी से एक उत्तर दें।

समापन

मैं इसे ठीक से कैसे सिंक्रनाइज़ कर सकता हूं? क्या pthread_mutex_ (अन) ताला काम करना चाहिए? यदि नहीं, तो मैं सी ++ थ्रेड और जावा थ्रेड के बीच सिंक्रनाइज़ करने के लिए क्या उपयोग कर सकता हूं?

जेएनआई पुल काम नहीं कर रहा है और मैं आगे और पीछे डेटा पास कर सकता हूं, यहां कोई जेएनआई-विशिष्ट सी ++ कोड नहीं दिया गया है। प्रश्न विशेष रूप से सी + + / जावा धागे के बीच उचित सिंक्रनाइज़ेशन के बारे में है जो अन्यथा ठीक से संचार कर रहे हैं।

जैसा कि पहले बताया गया है, मैं मतदान योजना से बचना पसंद करता हूं, लेकिन इससे एक और सवाल हो सकता है। विरासत सी ++ कोड X / motif में यूजर इंटरफेस का अपना हिस्सा प्रदर्शित करता है, और अगर मुझे सही ढंग से याद आती है तो ऊपर के सी ++ धागा प्रदर्शन के लिए घटना धागा होता है। इस धागे को जावा इवेंट डिस्पैच धागा खत्म हो जाएगा, जब इस क्लास के लिए जावा यूजर इंटरफेस प्लग हो जाएंगे, हालांकि अब जावा थ्रेड एक स्वचालित टेस्ट धागा है; किसी भी तरह से, यह एक अलग जावा धागा है

सी ++ थ्रेड जेवीएम से जुड़ा हुआ है वास्तव में, वह सी ++ थ्रेड है जो जेवीएम बनाया है, इसलिए यह डिफ़ॉल्ट रूप से संलग्न होना चाहिए।

मैं इस प्रोग्राम में अन्य जावा उपयोगकर्ता इंटरफ़ेस तत्वों में प्लगिंग के साथ सफल रहा हूं, लेकिन यह पहली बार है कि सी ++ को जावा से गैर-परमाणु डेटा की आवश्यकता होती है, जिसे सिंक्रनाइज़ किए जाने की आवश्यकता होती है। क्या ऐसा करने का आम तौर पर स्वीकार किया गया सही तरीका है?





jni