1

I have a udp socket running on a separate thread. I need to get certain data only periodically, something like:

void runThread(udpSocketObj s, std::promise<int>* f1, std::promise<int>* f2)
{
    s->rec(ret);
    ...
    f1->set_value(someValue in ret);
    f2->set_value(someOtherValue in ret);
}
int main(int argc, char **argv){
    
    std::promise<int> p1, p2;
    std::future<int> f1 = p1.get_future();
    std::future<int> f2 = p2.get_future();
    mythread = std::thread(runThread, myScoketObj, &p1, &p2);
    mythread.detach();
    int myV1 = f1.get();
    int myV2 = f2.get();

}

f1 and f2 should only be updated periodically. If i have a receiving loop going in runThread, when they are updated the second time, it throws a "promise already satisfied" error. Is it possible to keep mySocket in a receiving loop but get the future data updated only when needed?

DHT201703
  • 11
  • 2
  • 4
    `promise`/`future` are one-shot objects. You can't reuse them. You want a more complicated structure, like a thread-safe queue. – François Andrieux Jul 14 '21 at 17:12
  • 1
    Beware of `std::thread::detatch`. It is usually an error to use it, it's presence is often a sign of a design problem. Try to get your program to work correctly with `.join` instead. – François Andrieux Jul 14 '21 at 17:13
  • I notice you pass your promises by pointer. In C++, you should favor pass-by-reference if the argument can't be `nullptr`. This can be a little tricky with `std::thread` but you can read about it here : [Passing object by reference to std::thread in C++11](https://stackoverflow.com/questions/34078208/passing-object-by-reference-to-stdthread-in-c11/34078246). But in this case, you usually don't want to hang on to the promise in `main`. You should be able to `std::move` the promises instead. – François Andrieux Jul 14 '21 at 17:14
  • yes, I did try to join it but it would be like i create then join a thread multiple times a second? Do i need to delete the thread object every time? Sorry, not a C++ person to begin with.. Thank you so much! – DHT201703 Jul 14 '21 at 17:17
  • Seeing as the context of the question seems to be a UPD server, I assume you are asking about creating a thread on each accepted packet. This is independent of `join` vs `detatch`. If you are creating a `std::thread` and using `detatch` for each received packets, then creating multiple threads per second and destroying them is already what you are doing. But since UDP is connectionless, it's hard to know how you want to thread the communications or what you want to achieve by using threads. You would need to share more details to get better advice. – François Andrieux Jul 14 '21 at 17:40
  • Thank you so much, really appreciate it! My udp socket here is a server. The socket is a global variables and bound to port/ip in the constructor. Here, I am only trying to receive. All incoming packets should be received on a infinite loop. As you suggested, i will put all the receiving stuff into a thread-safe queue. If i run the thread detached, it should just receive forever, right? I do need to send on the same socket. Do I need a lock on the socket? Not there yet and not sure what would be the best way to do it. Truly newbie on this. Thanks again. – DHT201703 Jul 14 '21 at 18:48
  • 1
    You can change this to use `join` instead of `detatch` but storing the `std::thread` object somewhere that outlives the processing loop it runs, then calling join when the server is shutdown. But if your processing loop is an infinite loop with no exit mechanism, there won't be a difference between `detatch` and `join` because the program ends in what is essentially a sudden crash either way. Eventually, you'll want to sort that out. Then, a logical place to store the `std::thread` and a logical place to `join` it should emerge. – François Andrieux Jul 14 '21 at 20:11

0 Answers0