Синхронные обратные вызовы в C
У меня есть несколько методов в C "DoSomething1()
","DoSomething2()
",...,"DoSomethingN()
"этот запрос для некоторых данных. Эти методы могут быть вызваны одновременно. Данные находятся в другом процессе, и в настоящее время связь между текущим процессом и этим другим процессом осуществляется с использованием сокета.
Как я могу создать синхронный обратный вызов?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.
Спасибо!
1 ответ
Решение состояло в том, чтобы заблокировать поток после прохождения запроса, а затем добавить блокировку к вектору, который был виден потоку, который обрабатывает сокет запросов.
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);