интерактивный вызов функций из динамической библиотеки без ожидания возврата (python, ctypes)

Я делаю интерфейс моей простой библиотеки 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
}
}

0

Решение

Нет способа сделать это внутри одного потока. Вы должны использовать multithreading или же multiprocessing для этого: один из потоков (thread B) должен принимать команды и запускаться (через выполнение функций вашего dll) и другого потока (thread A — поток с основной логикой) должен посылать эти запросы и время от времени проверять результаты.

Конечно, ваши dll могут выполнять такую ​​работу сами, но, как я вижу, они этого не делают (поскольку ваш вопрос существует).

На самом деле не ожидайте, что в ответ на ваш вопрос кто-то научит вас полностью работать с многопоточностью. Эта проблема слишком широка. Есть книги, статьи и курсы по многопоточности. Вы можете посмотреть на них.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]