В функции JNI C ++ (полупсевдо включенной ниже), по крайней мере, один (и, возможно, два) дополнительных потока (ов), созданных в client_ = new VClient(&callback_)
линия. Я полагал, что завершения этой функции будет достаточно, но, очевидно, когда следующая функция (другая функция JNICALL) вызывается «немедленно» после этого, это вызывает SEGFUALT («немедленно» находится в кавычках, потому что функция вызывается так же быстро, как и кто-то может нажать следующую кнопку). Я полагаю, что это потому, что создание new VClient
еще не завершена к тому времени, когда функция Init возвращается и вызывается следующая функция, так как client_
используется в следующей функции.
Я довольно новичок во всем этом многопоточном бизнесе, и я не уверен, правильное ли это мышление. Я привык кодировать выполнение последовательно, поэтому, когда код переходит от client_
линия, потому что все с этой линией завершено. Возможно ли, чтобы код перешел из этой строки и вернулся из функции JNI Init до новой VClient
был полностью создан? Если это так, как бы мне заставить эту функцию ждать, пока класс / объект не будет завершен?
JNIEXPORT void JNICALL Java_com_ClassDir_Init(JNIEnv *env, jobject obj)
{
LOGI("%s", __PRETTY_FUNCTION__);
if(!client_)
{
LOGI("Initializing client");
client_ = new VClient(&callback_);
[Bunch of JNI/JAVA class and methodID lookup and saving]
}
else
LOGI("Client already initialized");
}
* The callback_
это класс, который обрабатывает отправку сигналов типа enum в JNI / JAVA для обновления информации о ходе выполнения программы.
Вы сказали, что VClient
Конструктор создает потоки. Создание темы это синхронный процесс: выполнение VClient
ctor не продолжается до тех пор, пока поток не будет полностью создан, а также, скорее всего, не запущен, так как я не вижу другого вызова метода в VClient для этого. Что такое не синхронно, это Начните нити. Это не означает «полностью работоспособный», просто ваш основной поток дал указание созданному потоку начать работу в своем собственном контексте. Когда цикл выполнения нового потока настроен и введен, он полностью асинхронный (для вашей конструкции VClient) и вплоть до планирования потока. Таким образом, если ваша «следующая функция JNI» пытается вызвать этот поток и использовать там некоторые ресурсы, ресурс должен быть уже доступен (это означает, что вы ожидаете, что новый поток уже продвинулся до точки его доступности) и доступа к этот ресурс должен быть защищен для безопасного доступа.
Так что вам нужно стать менее новым в этом многопоточном бизнесе 🙂 Посмотрите на два основных строительных блока:
Они реализованы по-разному в различных API для каждой ОС и для каждой платформы. Даже разные фреймворки в одной и той же ОС имеют тенденцию быть разными. Но философия равна.
Кстати, я считаю само собой разумеющимся, что client_
объявляется таким образом, что он не выходит за рамки, когда «следующая функция JNI» пытается использовать это. Что, вероятно, означает глобальную переменную в реализации JNI — я не вижу никакой оболочки класса для нативного кода.
Нет. Строка кода, вызывающая ‘new VClient ()’, не переходит к следующей строке, пока не выйдет конструктор VClient. Исполнение является последовательным. Ваша проблема в другом месте.