Что я делаю
Я запускаю клиент thrift cob (сгенерированный сервис класс CobClient), используя TEvhttpClientChannel. У меня есть event_base_l oop () в одном потоке и вызов метода RP C в другом потоке (основной поток). Я использую канал обещания-будущего между обратным вызовом и основным потоком, чтобы уведомить, когда ответ получен. Примерно так:
static void RPCMethod_clientReturn(event_base* base, std::promise<int> * prom,
Response * res , MyCobClient* client){
try{
client->recv_RPCMethod(*res);
prom->set_value(1);
}
catch(TException& e) {
std::cout << "Exception in thrift client: " << e.what() << std::endl;
prom->set_value(0);
}
}
int main() {
evthread_use_pthreads();
event_enable_debug_logging(EVENT_DBG_ALL);
struct event_base * base = event_base_new();
std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
std::shared_ptr<TAsyncChannel> channel(
new TEvhttpClientChannel(server.c_str(), "/", server.c_str(), port, base));
// THE CLIENT
MyCobClient* client =
new MyCobClient(channel, protocolFactory.get());
// RUN THE EVENT LOOP IN SEPARATE THREAD
std::thread event_thread = std::thread(&event_base_loop, base, EVLOOP_NO_EXIT_ON_EMPTY);
// INVOKE RPCMethod. Wait for response before invoking next RPCMethod.
for(int i; i < REQS; i++){
std::promise<int> prom;
Request req;
Response res;
auto fut = prom.get_future();
//MAKE THE RPC CALL
client->RPCMethod(std::bind(RPCMethod_clientReturn,
base,&prom,&res,
std::placeholders::_1),
req);
// WAIT FOR CALLBACK TO SET THE PROMISE (i.e. WAIT FOR RESPONSE)
fut.wait();
if (fut.get() == 0){
std::cout << "Error..." << std::endl;
}
}
}
К моей проблеме
Я получаю ошибку подтверждения при выполнении !ningQueue.empty () в TEvhttpClientChannel :: fini sh. Отладочная информация, которая выводится до появления ошибки здесь .
Надеюсь, есть кто-то, кто сталкивался с подобной проблемой раньше. Я попытался просмотреть исходный код, и единственная возможность, которую я вижу для этого, находится в TEvhttpClientChannel. cpp: 85 и TEvhttpClientChannel. cpp: 90 , что основной поток вытесняется после строки 85 (запрос make / register), но до строки 90 (pu sh toquequeueue), а поток event_l oop завершает событие и попадает в TEvhttpClientChannel :: fini sh (утверждает очередь завершения не пустая и тянет из очереди завершения) до того, как основной поток доберется до pu sh до очереди завершения в строке 90. Просто дикое предположение, что ... Вы действительно не знаете, как я мог это проверить .. Возможно, GDB? Возможно, TEvhttpClientChannel принципиально не предназначен для запуска события l oop в отдельном потоке?