Является ли callstack безопасной для языка структурой данных? Квазар + Фортран?
У нас есть Java-приложение, подкрепленное двоичным файлом с фортраном, который мы активно развиваем. Я в основном на стороне Java, и я считаю своей работой защищать людей, которые работают на Фортране, от некоторых неприятных системных вещей, которые могли бы в противном случае их беспокоить, таких как параллелизм и не заставлять их выставлять сложные API.
Одно из решений, которое я принял в этом направлении, состояло в том, чтобы передать обратный вызов в стиле JNA из Java в наши двоичные файлы на языке Fortran. Когда этот обратный вызов будет выполнен, наш стек вызовов будет выглядеть примерно так:
UIframework.click.java -- com.sun#1234
OurCode.UIHandlers.java -- our.code#2345
OurCode.doHeavyComputation.java -- our.code#4567
JNASurrogates.java -- com.sun.jna#456
JNASurrogates.proxy.f99 -- com.sun.proxies
HeavyComputation.f99 -- /code/algorithm.f99#1234
JNASurrogates.executeCallback.proxy.f99 -- com.sun.proxies
JNASurrogates.java -- com.sun.jna#1234
OurCode.computationComponents.java -- our.code#6789
//bottom of callstack
Мой вопрос - один из потоков: как будут обрабатываться два потока доступа к одной и той же in-memory Fortran DLL? Мой вопрос коренится в точных деталях того, как стеки вызовов обрабатываются в памяти: для того, чтобы компилятор фортрана мог генерировать код, который можно вызывать из JNA, без использования одного затвора счетчика программ, у этого компилятора должен быть какой-то поделились с JVM пониманием того, где должен храниться стек вызовов. Предоставляет ли нам X86 какой-то отдельный контейнер счетчика программ, который Pthreads
, java.lang.Thread
и другие библиотеки потоков все используют, обеспечивая безопасную изоляцию стека вызовов?
Чтобы сделать вещи действительно интересными, я также спорю об использовании Quasar - для тех, кто незнаком, Quasar предлагает то, что он называет "волокнами", то есть "легкими потоками", реализованными стековыми подпрограммами, то есть Quasar выполняет прямые манипуляции со стеком. реперы.
Проблема в том, что, хотя я концептуально весьма рад раскрыть OurCode.computationComponents
в качестве обратного вызова, некоторые бизнес-требования диктуют, что я не могу. Вместо того, чтобы просить наших выдающихся фортрановских программистов преобразовать существующий код во что-то с явными точками входа и выхода, я бы предпочел использовать сопрограмму для использования нашего существующего кода.
Идея состоит в том, что совместная рутина даст OurCode.computationComponents.java
приводя любые аргументы, которые были переданы в computationComponents
от HeavyComputation.f99
как возвращаемое значение для звонящего doHeavyComputation
, Затем вызывающая сторона выполняет ту работу, которую обычно выполняет обратный вызов computationCompoennts, передавая результат из resumeHeavyComputation
, что приведет к computationComponents
и в конечном итоге вернуться к HeavyComputation.f99
Конечно, я могу сделать все это с помощью очереди блокировки и нескольких потоков, но попытка ограничиться использованием одного потока означает, что я получу некоторую возможность познакомиться с Quasar, что хорошо по нескольким причинам.
Может ли Quasar обрабатывать и безопасно восстанавливать стек, такой же сложный, как и тот, который мы используем?
1 ответ
ОС предоставляет потоки. Другие модели программирования (Java, Quasar и т. Д.) Должны основываться на этом, если они находятся в пространстве пользователя. Ваш "легкий поток" Quasar все еще будет жить в контексте вашего процесса ОС и потоков ОС. Поскольку потоки вашей ОС могут совместно использовать память, то же самое можно сказать и о "легких потоках". Обратные вызовы в Java через JNA из разных "легких потоков" будут выглядеть в одном и том же потоке с Java-отображением (и, следовательно, в одном и том же собственном потоке).
Что бы ни складывалось во время выполнения, Quasar перетасовывает свои сопрограммы, в значительной степени непрозрачно для Java.