#python #c #callback #ctypes
Вопрос:
Это мой тестовый код на Python, разрабатывающий соединитель Python для базы данных TDengine. Исходный код размещен на https://github.com/taosdata/TDengine/tree/feature/TD-3048-python-full-feature-api/src/connector/python .
В тесте он хочет выполнить асинхронный запрос из двух таблиц с одной и той же функцией обратного вызова. Обе таблицы содержат несколько строк. В коде C это будет нормально. Но в Python обратный вызов работает только в первом запросе.
Кто-нибудь может дать мне несколько советов о том, как это проверить/решить?
from taos import *
from ctypes import *
import taos
import pytest
import time
@pytest.fixture
def conn():
return taos.connect()
def fetch_callback(p_param, p_result, num_of_rows):
print("fetched ", num_of_rows, "rows", c_void_p(p_result))
p = cast(p_param, POINTER(Counter))
result = TaosResult(p_result)
if num_of_rows == 0:
print("fetching completed")
p.contents.done = True
result.close()
return
if num_of_rows < 0:
p.contents.done = True
result.check_error(num_of_rows)
result.close()
return None
for row in result.rows_iter(num_of_rows):
# print(row)
None
p.contents.count = result.row_count
result.fetch_rows_a(fetch_callback, p_param)
def query_callback(p_param, p_result, code):
# type: (c_void_p, c_void_p, c_int) -> None
if p_result == None:
return
result = TaosResult(p_result)
if code == 0:
result.fetch_rows_a(fetch_callback, p_param)
result.check_error(code)
def query_callback2(p_param, p_result, code):
# type: (c_void_p, c_void_p, c_int) -> None
if p_result == None:
return
result = TaosResult(c_void_p(p_result))
if code == 0:
result.fetch_rows_a(fetch_callback, p_param)
result.check_error(code)
class Counter(Structure):
_fields_ = [("count", c_int), ("done", c_bool)]
def __str__(self):
return "{ count: %d, done: %s }" % (self.count, self.done)
def test_query(conn):
# type: (TaosConnection) -> None
counter = Counter(count=0)
conn.query_a("select * from log.log", query_callback, byref(counter))
ct2 = Counter(count = 0)
conn.query_a("select * from log.dn", query_callback, byref(ct2))
while not counter.done or not ct2.done:
print("wait query callback")
time.sleep(1)
print(counter,ct2)
conn.close()
if __name__ == "__main__":
test_query(taos.connect())
Комментарии:
1. Если функция C не использует статические переменные, вы должны иметь возможность вызывать ее в нескольких потоках.