Как установить результат будущего \ добавить в очередь из другого потока в Cython?

У меня есть C ++ DLL, которая работает с несколькими потоками.
Поэтому я обернул эту библиотеку Cython и создал специальную функцию обратного вызова получателя, которая должна добавить некоторые результаты в asyncio.Queue.

cdef void __cdecl NewMessage(char* message) nogil:

Я отметил это как nogil, этот обратный вызов вызывает из другого потока.
В этом обратном вызове я просто использую:

with gil:
print("hello")  # instead adding to Queue. print("hello") is more simple operation to demostrate problem

И попал в тупик здесь.
Как это решить?

Объявление обратного вызова C ++ (заголовок):

typedef void (*receiver_t)(char*);
void SetReceiver(receiver_t new_rec);

каст:

static receiver_t receiver = nullptr;

void SetReceiver(receiver_t new_rec)
{
printf("setted%i\n", (int)new_rec);
a = 123;
if (new_rec != nullptr)
receiver = new_rec;
}

Код Cython:

cdef extern from "TeamSpeak3.h":
ctypedef void (*receiver_t) (char*) nogil
cdef void __cdecl SetReceiver(receiver_t new_rec) nogil

cdef void __cdecl NewMessage(char* message) nogil:
with gil:
print("hello")

SetReceiver(NewMessage)

Полный код:
.час http://pastebin.com/ZTCjc6NA

.CPP http://pastebin.com/MeygA8im

.дарохранительница http://pastebin.com/k4X9c54P

.ру http://pastebin.com/1YV7tMiF

0

Решение

Это немного предположение, но у вас, вероятно, работает цикл Cython / C / C ++, который содержит GIL и никогда не выпускает его. Затем обратный вызов вынужден ждать его вечно.

В обычном коде Python GIL выпускается каждые несколько инструкций, если его ожидает другой поток. В Cython это не происходит автоматически. Один из способов убедиться, что это происходит так часто, заключается в том, чтобы выполнить цикл:

while True:
# ... do stuff
with nogil:
pass

Это гарантирует, что GIL высвобождается один раз за цикл.

К сожалению, для меня не очевидно, где у вас есть основной цикл. Интересно, если это внутри connect в вашем PyTeamSpeak3 класс, и, возможно, изменив определение подключения к:

def connect(self):
with nogil:
self.thisptr.Connect()

может помочь?

1

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

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

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