У меня есть экспериментальный язык программирования, где программы компилируются в c. Я написал оболочку cython, которая оборачивает скомпилированный код c и позволяет вызывать его из python. Это позволяет использовать скомпилированные программы в качестве быстрых низкоуровневых функций внутри Python. Часто бывает так, что мы хотим использовать несколько таких программ в одной и той же программе Python. Тогда конвейер для создания и импорта каждой программы:
- Скомпилируйте программу в c с помощью компилятора.
- Скомпилируйте код c в общий объект .so с помощью gcc.
- Создайте оболочку .pyx, которая может получить доступ к функциям c, которые мы хотим использовать, из python.
- Скомпилируйте оболочку .pyx с помощью cythonize, чтобы сгенерировать файл .so.
- Импортируйте общий объект .so, используя функцию импорта Python.
На практике шаги 1-4 фактически объединяются в один внешний вызов для выполнения с использованием sys, при этом сгенерированный Makefile выполняет каждый из 4 шагов. Это позволяет нам вызывать make через внешний вызов с помощью sys, а затем импортировать скомпилированную программу, даже не выходя из python.
Скомпилированная программа может иметь вероятностные конструкции. В частности, решения о ветвлении определяются случайными числами. Для этого делаются вызовы родного языка c
rand()
функция. Когда скомпилированная программа-оболочка импортируется в python, выполняется вызов импорта для сгенерированного общего объекта .so, который создается с помощью cythonize. До сих пор я пытался позвонить
srand(<long int>time(NULL)
из файла .pyx, который упаковывает каждую скомпилированную программу. Насколько я могу судить, каждый импортированный .so будет эффективно использовать свой собственный генератор случайных чисел. Но из документов мне совсем не ясно, так ли это.
В конечном счете, я хочу, чтобы разные .so использовали один и тот же генератор случайных чисел, но я понятия не имею, как это сделать. Мы будем очень признательны за любые рекомендации. Большая часть кода слишком длинная, чтобы включать его сюда, но если вы хотите увидеть какие-либо фрагменты (например, «как вы делаете x-компонент?»), я с радостью вам помогу.
Даже если все, что вы можете предложить, — это объяснение того, как вызовы rand() будут взаимодействовать между различными общими объектами, сгенерированными с помощью cythonize, этого может быть достаточно, чтобы выработать решение.
Заранее спасибо!
nm my_extension.so | grep rand
, если уrand@@GLIB_XXX
есть атрибутU
(скорее всего), то его будет обеспечиватьlibc.so
и состояние разделяется между всеми модулями. - person ead   schedule 08.08.2019