Синхронные обратные вызовы в 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);
Другие вопросы по тегам