简体   繁体   English

C 中的同步回调

[英]Synchronous callbacks in C

I have multiple methods in C DoSomething1() , DoSomething2() , ..., DoSomethingN() that request for some data.我在 C DoSomething1() , DoSomething2() , ..., DoSomethingN()中有多种方法来请求一些数据。 These methods can be called concurrently.这些方法可以同时调用。 The data resides in a different process and currently the communication between the current process and that other process is done using a socket.数据驻留在不同的进程中,当前当前进程和其他进程之间的通信是使用套接字完成的。

How can I create a synchronous callback GetSpecialValue() that requests the data using the aforementioned socket and then, when the socket replies, returns the answer back to the specific DoSomethingN() that has requested it?如何创建同步回调GetSpecialValue()使用上述套接字请求数据,然后在套接字回复时将答案返回给请求它的特定DoSomethingN()

Keep in mind that I have a lot of methods that work with a single socket and pass requests that their reply should return to the specific method that initiated the call.请记住,我有很多方法可以使用单个套接字并传递请求,它们的回复应该返回到发起调用的特定方法。 Those methods work in different threads.这些方法在不同的线程中工作。

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

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

I know that some people use libevent for callbacks, but I don't think that you can return new parameters when the event is called.我知道有些人使用libevent进行回调,但我不认为您可以在调用事件时返回新参数。 Also, it's async and isn't part of the AOSP build ..此外,它是异步的,不是AOSP 构建的一部分..

Thanks!谢谢!

The solution was to lock the thread after the request was passed and then, add the lock to vector that was visible by the thread that handles the requests socket.解决方案是在请求传递后锁定线程,然后将锁定添加到处理请求套接字的线程可见的向量。

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);
...

When the response has returned from the socket, the response would be saved in a responses vector and the lock fetched from the vector and released.当响应从套接字返回时,响应将保存在响应向量中,并从向量中获取锁并释放。

...
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);
...

After the lock was released, the thread would continue and ask for the result, that will be returned from the vector.释放锁后,线程将继续并询问结果,该结果将从向量中返回。

...
return GetResponse(callbackId);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM