2016-10-06 6 views
1

У меня есть несколько методов в C "DoSomething1()", "DoSomething2()", ..., "DoSomethingN()", который запрашивает некоторые данные. Эти методы можно вызывать одновременно. Данные находятся в другом процессе и в настоящее время представляют собой связь между текущим процессом и другим процессом выполняется с использованием сокета.Синхронные обратные вызовы в C

Как создать синхронный обратный вызов «GetSpecialValue()», который запрашивает данные с использованием вышеупомянутого сокета, а затем, когда сокет отвечает, возвращает ответ обратно на конкретный «DoSomethingN()», который запросил его?

Имейте в виду, что у меня есть много методов, которые работают с одним сокетом и передают запросы, чтобы их ответ возвращался к определенному методу, инициировавшему вызов. Эти методы работают в разных потоках.

int DoSomethingN(int id) { 
    int returnValue = GetSpecialValue(id); 
    return returnValue; 
} 

int GetSpecialValue(int id) { 
    SendToProcessViaSocket(id); 
    int returnValue = ReceiveSocketAnswer(); 
    return returnValue; 
} 

Я знаю, что некоторые люди используют libevent для обратных вызовов, но я не думаю, что вы можете вернуть новые параметры, когда событие вызывается. Кроме того, он является асинхронным и не является частью AOSP build ..

Спасибо!

+1

Вещи работают синхронно по умолчанию - зачем вам нужно что-либо делать? Просто отправьте запрос, затем получите ответ ... – immibis

+0

Кажется, вам нужно использовать блокировку потоков, вы можете создать блокировку, которая вынимается функцией GetSpecialValue(), и освобождается функциями DoSomethingN(). – Alex

ответ

0

Решение заключалось в том, чтобы зафиксировать поток после того, как запрос был отправлен , а затем добавьте блокировку к вектору, который был виден потоком, обрабатывающим запрос.

std::tuple<int, pthread_mutex_t *, pthread_cond_t *, bool *> callbackData; 
pthread_mutex_t *reqMutexLock = (pthread_mutex_t *)malloc(sizeof(*reqMutexLock)); 
pthread_cond_t *reqCondition = (pthread_cond_t *)malloc(sizeof(*reqCondition)); 
bool *state = (bool *)malloc(sizeof(*state)); 

(*reqMutexLock) = PTHREAD_MUTEX_INITIALIZER; 
(*reqCondition) = PTHREAD_COND_INITIALIZER; 
(*state) = false; 

int callbackId = rand(); 

callbackData = std::make_tuple(callbackId, reqMutexLock, reqCondition, state); 

pthread_mutex_lock(reqMutexLock); 
SendRequest(callbackId, id); 
while (!(*state)) { 
    pthread_cond_wait(reqCondition, reqMutexLock); 
} 
pthread_mutex_unlock(reqMutexLock); 
pthread_mutex_destroy(reqMutexLock); 
free(reqMutexLock); 
free(reqCondition); 
... 

Когда ответ вернулся из гнезда, ответ будет сохранен в векторе ответов и замок извлеченной из вектора и освобожден.

... 
response = ReceiveResponse(); 
responsesList.push_back(response); 

... 
reqMutexLock = std::get<1>(callbackDataList[foundIndex]); 
reqCondition = std::get<2>(callbackDataList[foundIndex]); 
state = std::get<3>(callbackDataList[foundIndex]); 

pthread_mutex_lock(reqMutexLock); 
(*state) = true; 
pthread_cond_broadcast(reqCondition); 
pthread_mutex_unlock(reqMutexLock); 
... 

После того, как замок был выпущен, поток продолжался и запрашивал результат, который будет возвращен из вектора.

... 
return GetResponse(callbackId); 
Смежные вопросы