2014-12-26 13 views
6

Nel codice seguente, la funzione main() chiama la funzione request() che inter chiama la funzione th_request_async() che mm_th_done_cb().Il modo migliore per attendere il completamento della richiamata

Quale sarà il modo migliore ed efficace per procedere in main solo dopo l'esecuzione di mm_th_done_cb().

MANICHINO CODICE

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

mettere la chiamata per renderlo NULL prima dell'istruzione gratuita. –

risposta

4

Se C++ 11 è disponibile, è possibile std :: futuro

#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(); 
} 

oppure è possibile utilizzare la sincronizzazione mechanism.such come condition_variable, che è cross-platform .

#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(); funzione chiama la funzione mm_th_done_cb che è passata MyItemInfo.func = mm_th_done_cb; E nella funzione callback mm_th_done_cb recupero il valore richiesto per il quale ho chiamato th_request_async. – dearvivekkumar

+0

Nel mio caso devo chiamare 3 funzioni simili per ottenere il valore e prima devo aspettare. Ho bisogno di consigli per trattare tali scenari nel miglior modo possibile. – dearvivekkumar

+0

Main() sta chiamando request request() può richiedere sta chiamando th_request_async() che è una funzione di libreria che sta chiamando la funzione di callback registrata mm_th_done_cb() – dearvivekkumar

7

È possibile utilizzare 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; 
} 

Se non è necessario restituire alcun valore dalla richiamata, quindi è possibile utilizzare un paio std::promise<void> e std::future<void> .

Entrambi gli esempi nella risposta di wuqiang sono sbagliati.

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; 
} 
Problemi correlati