У меня большой код инженерного моделирования, настроенный для отправки данных через TCP-сокет. Я написал библиотеку C ++, которая читает из сокета, вот так:
bool read_next(monitor_buffer_object* obj)
{
int valread = 1;
valread = read(server_fd, buffer, buffer_size);
if (valread <= 0) return false;
return obj->try_build_from_bytes(buffer, 0, buffer_size);
}
Эта функция имеет оболочку Python, которая выглядит следующим образом:
static PyObject* bitcartinterlib_ReceiveObject(PyObject *self, PyObject *args)
{
PyObject* output = Py_BuildValue("");
external_monitor::monitor_buffer_object received_object;
bool result = external_monitor::read_next(&received_object);
if (result)
{
output = build_py_buffer_obj(&received_object);
}
received_object.dispose();
return output;
}
Следует отметить, что эти функции блокируют.
Теперь я написал Tkinter GUI in Python, который вызывает on_tick
в отдельном потоке основного потока.
def on_tick(self):
data_in = myCustomPythonModule.ReceiveObject()
if data_in is not None:
print(data_in)
else:
self.host.has_valid_connection = False
Примечание что self.host
является объектом, содержащим весь код события GUI, и вызов on_tick
зависит от self.host.has_valid_connection
, так что logi c предотвращает неопределенную блокировку.
Однако симуляция код передает эти объекты с несколько непредсказуемой скоростью. Например, скажем, 1 объект в секунду.
Проблема в том, что остальная часть GUI не может использоваться в течение времени, которое требуется для кода моделирования для передачи объекта. Это не удивительно благодаря GIL.
Мне интересно, есть ли простой способ обойти это? Может показаться, что мой единственный вариант сейчас - сделать неблокирующее чтение или обрабатывать многопоточность в C ++, но я бы хотел сделать потоковую обработку в приложении GUI ради простоты.