Я делаю интерфейс моей простой библиотеки C ++ для физического моделирования и визуализации с python. Я хотел бы использовать его в интерактивном режиме, то есть настраивайте параметры, вызывая функции из Python для интерпретации параметров во время симуляции / визуализации)
в настоящее время неинтерактивный сценарий выглядит так:
import numpy as np
import pyVis3D as vis
# inititalization
vis.lib.initWindow()
# modify visualization state - must do before call vis.lib.loop()
ts = np.linspace(0,2*np.pi,100)
poss = np.transpose( np.stack([ np.sin(ts), np.cos(ts), np.sin(ts*3) ]), (1,0) ).copy()
vis.polyline( poss )
# loop of visualization window update
vis.lib.loop(1000000) # I have to wait for return, cannot change anything interactively
Я хотел бы вместо этого как-то в Python интерпретировать:
>> import numpy as np
>> import pyVis3D as vis
>> vis.lib.initWindow() # inititalization
>> vis.lib.loop(1000000) # run loop
# modify state of vis.lib while vis.lib.loop() is running
>> ts = np.linspace(0,2*np.pi,100)
>> poss = np.transpose( np.stack([ np.sin(ts), np.cos(ts), np.sin(ts*3) ]), (1,0) ).copy()
>> vis.polyline( poss ) # I should see new curve in that window
Здесь интерфейс ctypes а здесь Библиотека C ++.
Я думаю, что решение связано с многопоточностью, но у меня нет опыта в этом. Я даже не уверен, должна ли эта многопоточность быть на стороне Python, C ++ или обоих.
Простой пример (C ++) … только думай, что я хочу setGlobVar()
вызывается из терминала Python glob_var
в то время как loop
работает, и loop
выходные данные отражают измененное состояние glob_var
double glob_var=0;
extern{
// this function should run on background, write out state each 10 ms
void loop(int n){
for(int i=0;i<n;i++){
SDL_delay( 10 ); // wait 10 ms
printf( "%f \n", glob_var ); // each iteration write current state of glob_var
}
}
// this function should be called from python terminal
void setGlobVar( double f ){
glob_var = f; // change state of glob_var
}
}
Нет способа сделать это внутри одного потока. Вы должны использовать multithreading
или же multiprocessing
для этого: один из потоков (thread B
) должен принимать команды и запускаться (через выполнение функций вашего dll) и другого потока (thread A
— поток с основной логикой) должен посылать эти запросы и время от времени проверять результаты.
Конечно, ваши dll могут выполнять такую работу сами, но, как я вижу, они этого не делают (поскольку ваш вопрос существует).
На самом деле не ожидайте, что в ответ на ваш вопрос кто-то научит вас полностью работать с многопоточностью. Эта проблема слишком широка. Есть книги, статьи и курсы по многопоточности. Вы можете посмотреть на них.
Других решений пока нет …