2014-12-26 7 views
6

В приведенном ниже коде функция main() вызывает функцию запроса(), которая вызывает функцию вызова th_request_async(), которая mm_th_done_cb().Лучший способ ожидания завершения обратного вызова

Каким будет лучший и эффективный способ продолжить работу только после выполнения команды mm_th_done_cb().

DUMMY КОД

int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data) 
{ 
    return 0; 
} 

void request() 
{ 
    th_request_s MyItemInfo; 
    strncpy(MyItemInfo.origin_path, szUrl, 1024+1); 
    MyItemInfo.orientation = 0; 
    MyItemInfo.func = mm_th_done_cb; 
    MyItemInfo.used_cache = 1; 
    th_request_async(MyItemInfo); 
} 


int main() 
{ 
    request(); 
    // Here I need to do something only after mm_th_done_cb() has been excuted. 
} 
+0

поставить вызов, чтобы сделать это NULL перед свободным заявлением. –

ответ

4

Если C++ 11 есть в наличии, вы можете StD :: Будущее

#include <future> 
int main() 
{ 
    request(); 
    std::future<int> myFuture = std::async(mm_th_done_cb); 
    //wait until mm_th_done_cb has been excuted; 
    int result = myFuture.get(); 
} 

или вы можете использовать синхронизацию mechanism.such в condition_variable, которая является кросс-платформенной ,

#include <condition_variable> 
std::mutex mtx; 
std::condition_variable cv; 
int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data) 
{ 
    cv.notify_one(); 
    return 0; 
} 

int main() 
{ 
    request(); 
    unique_lock<std::mutex> lck(mtx); 
    cv.wait(lck); 
    return 0; 
} 
+0

th_request_async(); функция вызывает функцию mm_th_done_cb, которая передается MyItemInfo.func = mm_th_done_cb; И в функции обратного вызова mm_th_done_cb я получаю необходимое значение, для которого я вызвал th_request_async. – dearvivekkumar

+0

В моем случае я должен вызвать 3 аналогичные функции, чтобы получить значение, и до этого я должен ждать. Мне нужен совет для решения таких сценариев наилучшим образом. – dearvivekkumar

+0

Main() вызывает вызов вызывающего запроса() может запросить вызов th_request_async(), который является функцией библиотеки, которая вызывает зарегистрированную функцию обратного вызова mm_th_done_cb() – dearvivekkumar

7

Вы можете использовать std::promise:

std::promise<int> promise; 

int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data) 
{ 
    promise.set_value(error_code /*this value will be returned by the future.get()*/); 
    return 0; 
} 

int main() 
{ 
    std::future<int> future = promise.get_future(); 
    request(); 
    int value = future.get(); 
    return 0; 
} 

Если вам не нужно возвращать любое значение из функции обратного вызова, то вы можете использовать std::promise<void> и std::future<void> пару ,

Оба примера в ответе wuqiang неверны.

1.

#include <future> 
int main() 
{ 
    request(); 

    // WRONG: Here we don't want to call 'mm_th_done_cb' ourselves. 
    std::future<int> myFuture = std::async(mm_th_done_cb); 

    //wait until mm_th_done_cb has been excuted; 
    int result = myFuture.get(); 
} 

2.

#include <condition_variable> 

std::mutex mtx; 
std::condition_variable cv; 

int mm_th_done_cb(int error_code, th_result_s* th_result, void*  user_data) 
{ 
    cv.notify_one(); 
    return 0; 
} 

int main() 
{ 
    request(); 

    // WRONG: If the 'request' finishes quickly, then the 'mm_th_done_cb' 
    // callback will be called and will notify the condition variable before 
    // the following lines execute, i.e. before the main thread starts 
    // waiting on the condition variable. Thus the 'cv.wait(lck)' will 
    // never return. 

    unique_lock<std::mutex> lck(mtx); 
    cv.wait(lck); 
    return 0; 
} 
Смежные вопросы