Search code examples
c++concurrencypthreadspthread-join

How to return a double value from pthread in c++?


After reading this thread: How to return a value from thread in C on how to return an integer value from a pthread I tested to see if it could work for a double, but it didn't. Is there a way to return a double, long or a string from the pthread process like described in the original thread instead of returning the integer number 42?

If yes how?

And if I have a static array of 10 positions and 10 pthreads modifiying different positions each time, will I have trouble? AN example would be like "thread 0 modifies only array[0], thread 1 modifies only array[1] and so on".


Solution

  • These are just reformulations of Steve Jessop's C solution into C++. These toy examples (note the lack of error checking) use templates to make it obvious how to change the code to use some type other than double. For example, the double could be replaced with a class type if more than one value needed to be returned after the work is done. In practice, the base class and template would likely be removed and the work() method of MyWorker would be called directly by the invoker rather than via a virtual method.

    First, using pthread:

    #include <iostream>
    #include <pthread.h>
    
    class WorkerBase {
    protected: virtual ~WorkerBase () {}
    public:    virtual void * work () = 0;
    };
    
    template <typename T>
    struct Worker : public WorkerBase { T result; };
    
    extern "C" void *invoke_worker (void *arg) {
        return static_cast<WorkerBase *>(arg)->work();
    }
    
    struct MyWorker : public Worker<double> {
        void * work () {
            result = 4.2;
            return 0;
        }
    };
    
    int main () {
        pthread_t t;
        MyWorker w;
        pthread_create(&t, 0, invoke_worker, &w);
        pthread_join(t, 0);
        std::cout << "result: " << w.result << std::endl;
        return 0;
    }
    

    Second, using C++11 std::thread:

    #include <iostream>
    #include <thread>
    
    class WorkerBase {
    protected: virtual ~WorkerBase () {}
    public:    virtual void work () = 0;
               static void invoke (WorkerBase *w) { w->work(); }
    };
    
    template <typename T>
    struct Worker : public WorkerBase { T result; };
    
    class MyWorker : public Worker<double> {
        void work () { result = 4.2; }
    };
    
    int main () {
        MyWorker w;
        std::thread t(MyWorker::invoke, &w);
        t.join();
        std::cout << "result: " << w.result << std::endl;
        return 0;
    }
    

    You had another question in your post that I had missed:

    And if I have a static array of 10 positions and 10 pthreads modifiying different positions each time, will I have trouble?

    Whether or not this gives you trouble will likely depend on the array element type and your hardware architecture. In practice, I have not observed this being a problem on x86 architectures for array elements that are aligned on machine word boundaries.