1

I want to run two threads, one for each class I have. But I want them to be indepedent. For example, I have something like that:

class A
{
    pthread_t threadA;

    void runThreadA() { pthread_create(... arguments_here ...)};
}

class B
{
    pthread_t threadB;

    void runThreadB() { pthread_create(... arguments_here ...)};
}

Currently I create and run the two threads internally for each class, but my main is like this:

main()
{
    A.runThreadA();
    B.runThreadB();

    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);

    return 0;
}

How can I join the two threads also internally, causing the two threads two run in parallel?

Hope I am understandable.. Thank you

maria
  • 467
  • 1
  • 5
  • 19
  • 1
    Can't you just put the `pthread_join` in the class destructor? – NathanOliver Jul 11 '16 at 13:47
  • @NathanOliver joining in destructor is not a good idea. Maria you can use thread pool to achieve needed functionality. – paweldac Jul 11 '16 at 13:56
  • What do you mean by "join them internally"? – user253751 Jul 11 '16 at 14:02
  • @immibis with "join them internally" I mean that I don't want to have to call inside the main() the 'pthread_join()' function. I want it to happen automatically inside a class member function. – maria Jul 11 '16 at 14:26
  • @maria So make a class member function that calls `pthread_join`, and then call it? I don't understand the problem. – user253751 Jul 11 '16 at 14:34
  • @immibis I am building an API and don't want the programmer to have to think about the threads. I just want them to call a function like A.commenceExecution() (which is like A.runThreadA()) and the other things to be done internally. But if I call pthread_join inside the A.runThreadA() function, the two threads (A and B) cannot run in parallel.. – maria Jul 11 '16 at 14:38
  • @maria When do you want the thread to be joined? – user253751 Jul 11 '16 at 14:39
  • @immibis the thing is I don't know everything about threads. I am learning them now. I want a way to run two threads from different classes indepedently and in parallel. I want to give the programmer the possibility to run a single or both threads only calling A.runThreadA() or/and B.runThreadB() functions. – maria Jul 11 '16 at 14:43
  • @immibis and if I call pthread_join(threadA, NULL) inside runThreadA() function, then this thread will not let the threadB to begin. So no parallelism. – maria Jul 11 '16 at 14:44
  • @maria If you don't want to join a thread ever, then just use `pthread_detach` instead. – user253751 Jul 11 '16 at 14:49
  • @immibis Maybe I have not understood exactly what pthread_detach does, but I think it's not what I want because if I call it then the threads are being terminated with the termination of main(). – maria Jul 11 '16 at 15:11
  • @paweldac Actually what NathanOliver suggested, worked. But can you tell me why it's not a good idea? – maria Jul 11 '16 at 15:14
  • 1
    @maria read more about RAII. Destructors can't easily report errors, nor fail gracefully. Desctructors have no return value and throwing exceptions is leading to UB/Terminating of application. http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor?lq=1 – paweldac Jul 11 '16 at 15:18

1 Answers1

1

I'm going to leave this as an answer because I don't have privileges yet to comment, but I'll give it my best shot. I'm going to interpret that when you say join threads internally, that you mean inside the class and automatically, without having to write the extra join lines in the main function. In short, the answer is yes. You can call join from inside of a class, but it is somewhat ineffectual to do so, for the following reason.

Lets consider this example (I'm going to use std::thread because I'm more comfortable with it, but pthread will work very much the same):

class1
{
    std::thread *t1;
    void DoWork1();
    void CreateThread1() { 
        t1= new std::thread(&class1::DoWork1, this)
        JoinThread1();
    }
    void JoinThread1(){
        if (t1.joinable()) {
            t1.join();
        }
    }

};

class2
{
    std::thread *t2;
    void DoWork2();
    void CreateThread2() { 
        t2= new std::thread(&class2::DoWork2, this)
        JoinThread2();
    }
    void JoinThread2(){
        if (t2.joinable()) {
            t2.join();
        }
    }
};

Now we have theoretically completed this goal that every time we call Class1::CreateThread() it will automatically join as well without the added need of that join() call in the main thread. Except we have to remember that join() is a blocking function. Thus, if we call the Class1::CreateThread() in the main() then it will block until the thread is finished and joined and only then would be be able to call Class2::CreateThread(). So, if we tried this method, it should be obvious that the threads are not running in parallel nor is there any benefit at all to having used threads in the first place.

There is an argument for calling join() in the destructor of the class, but you would still need to call that destructor somewhere so we're still not getting that same automation that I think you're looking for.

That example was exceedingly simple, but it hopefully shows something important. That no matter where in the class you implement this functionality to join the thread, it will either block you from using your main thread to do other things like create a second thread (thus defeating much of the purpose of threads), or you will have to call this member function that joins the thread manually from your main anyway, the only difference would be that it would be a member function of the class rather than as you have it in the above example.

TLDR Because of the fact that join() is a blocking function it will have to be called "manually" in order to ensure that you can get any benefit out of the thread.

Scorch
  • 437
  • 1
  • 3
  • 14
  • Thank you very much, you are very understandable. Finally I set the threads "Detached" and created an infinite loop inside main(). I figured out this responses better to my needs. – maria Jul 11 '16 at 16:31