2013-09-30 20 views
5

Mamy aplikację Java Server (Linux 64 bit), która wykorzystuje kod natywny do przetwarzania danych. Natywny kod obsługuje również wszystkie problemy z wielowątkowością i został ostatnio ulepszony przełączaniem światłowodów za pomocą boost::context.Wątek natywny przełączany kontekstowo nie może być dołączony do JVM

Problem, przed którym obecnie stoimy, polega na tym, że AttachCurrentThread kończy się niepowodzeniem dla wątków z przełączaniem światłowodu. Po kilku długich sesjach debugowania i testowania znaleźliśmy przyczynę: JVM wydaje się odrzucać wątki z różnymi wskaźnikami stosu, niż dane przy jego tworzeniu.

Zweryfikowaliśmy to, po prostu dołączając do maszyny JVM z pliku pthread z zmodyfikowanym (ale ważnym) rsp, który nie powiedzie się po zmodyfikowaniu rsp.

Ewentualna poprawka wprowadziłaby pewien mechanizm obsługi zdarzeń w celu oddzielenia wywołań zwrotnych od wątków z przełącznikami światłowodowymi, ale naprawdę chciałbym tego uniknąć.

Czy ktoś zna obejście tego problemu?

Czy można wyłączyć sprawdzanie stosu (Oracle Java 1.7.0_40, 64-bitowe)?

Czy możemy zmodyfikować rodzime pthreads tak, aby wskazywało prawidłowe ramki stosów (wątpię, czy możemy)? (Nie możemy ustawić ramek stosu z góry).

+1

Wiem, że to nie odpowiada dokładnie na twój problem, ale możesz spróbować zastąpić włókna boost :: context (zaimplementowane w C++) za pomocą implementacji włókien w świecie Java. W tym kontekście są często nazywane coroutinami. Niektóre istniejące implementacje tutaj: [Dostępne biblioteki Coroutine w Javie] (http://stackoverflow.com/questions/2846428/available-coroutine-libraries-in-java) –

+0

Czy kiedykolwiek znalazłeś rozwiązanie tego problemu? Próbuję wykorzystać Boost.Coroutine i trzeba oddzwonić do Javy z JNI w taki sposób, który powoduje wiele błędów ... – NuSkooler

Odpowiedz

0

ZASTRZEŻENIE: To nie jest odpowiedź, ponieważ nie rozwiązuję bezpośrednio problemu z przełącznikiem RSP, ale było zbyt długo, aby umieścić go w komentarzu.

Z doświadczenia wiem, że powinieneś dołączyć natywny wątek dokładnie jeden raz i odłączyć dokładnie jeden raz przed jego wyjściem. Jeśli nie wiem, czy masz już dołączony, użyj tego kodu:

jint rv = vm->GetEnv((void**)&env, JNI_VERSION_1_6); 
if (rv == JNI_EDETACHED) { 
    vm->AttachCurrentThread((void**)&env, 0); 
} 

proponuję najpierw, upewniając się, że przywiązują do wątku dokładnie raz przed wszelkie związane z nimi włókna są tworzone, a dokładnie raz odłączyć od każdy natywny wątek przed jego wyjściem (lub w ogóle bez niego, jeśli wątki natywne nie kończą się).

Powiązane problemy