p_thread_join() question!

This is a discussion on p_thread_join() question! within the Linux Programming forums, part of the Platform Specific Boards category; I am struggling to learn using p_thread and threads in general by myself. I do not understand well the concept ...

  1. #1
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694

    p_thread_join() question!

    I am struggling to learn using p_thread and threads in general by myself. I do not understand well the concept of joinable threads. Can someone explain?
    Moreover, I have a question in detached one. What are they? I think that detached threads are created by you, but then are independent from you.

    In the code I am working on, I create some objects of a class named computePi and run its member function. I want to run the functions in parallel.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  2. #2
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    682
    How is this related to C++?

    Detached threads automatically clean up their resources when they terminate. They are useful in situations when, for instance, you want some thread do its job, but you don't care when the job is finished. When computing PI, you want to know when the result (or its portion) is computed, which means that you need a joinable thread.
    I never put signature, but I decided to make an exception.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    What actually concerns me the most is if this block of code allows the threads to run simultaneously or they are oblidged by me, to run in serial? The case is simplified to this:
    Code:
    for(...)
      foo();
    ...
    
    void foo() {
       int not_ok = pthread_create( &thread, NULL, &Job::RunHelper, job);
       if(not_ok) std::cout << "Error at creation\n";
       void * res;
       pthread_join(thread, &res);
       listener->handle((int)res, *job); // prints the result of the job
    }
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,527
    This is a unix/posix programming question, not C or C++.

    pthread_join() causes the caller to wait for another thread to terminate. If that other thread has terminated, pthread_join() immediately returns. The "joining" means that the end of the specified thread is at the point (of execution) where pthread_join() is called.

    A joinable thread is one that can be waited for using pthread_join(). A detached thread is one that can't be. The difference is that resources for a detached thread will be released as soon as it terminates, whereas resources for a joinable thread will not be released until it is specified in a call to pthread_join() or the program terminates.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  5. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by kmdv View Post
    How is this related to C++?

    Detached threads automatically clean up their resources when they terminate. They are useful in situations when, for instance, you want some thread do its job, but you don't care when the job is finished. When computing PI, you want to know when the result (or its portion) is computed, which means that you need a joinable thread.
    I understood the detached ones now. The joinable not really. I posted this here, because I am writing the code in C++ (but I was told not to use std::thread). If my question should be moved, I know that our admins can do that.


    EDIT for grumpy:
    >This is a unix/posix programming question, not C or C++.
    So, I shouldn't post these kind of questions in C board?

    >pthread_join() causes the caller to wait for another thread to terminate.
    So, in the example I gave above, the threads can be created and run in parallel. Right???? ::?
    Last edited by std10093; 01-06-2014 at 08:06 AM.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    2,539
    you might consider using std::bind/std::thread or boost::bind/boost::thread instead of raw pthreads function calls.
    Code:
    namespace life
    {
        const bool change = true;
    }

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,527
    Quote Originally Posted by std10093 View Post
    >This is a unix/posix programming question, not C or C++.
    So, I shouldn't post these kind of questions in C board?
    That's right.

    Quote Originally Posted by std10093 View Post
    >pthread_join() causes the caller to wait for another thread to terminate.
    So, in the example I gave above, the threads can be created and run in parallel. Right???? ::?
    Beginners answer: Logically, yeah. That is the point of threads. They keep executing concurrently until they terminate, or until one or more are forced to wait for something. pthread_join() is one way of forcing one thread to wait on another. Synchronisation (e.g. use of mutexes) is another way to force threads to wait on each other.

    Somewhat more technically correct answer: Actually, no. The host operating system and hardware (particularly number of distinct processors, cores) is what determines if threads execute in parallel. Two threads can execute on a single processor, since a component of the host (the scheduler) is responsible for allocating timeslices to each thread, during which the thread can execute some instructions. The scheduler interleaves execution of threads using a series of small timeslices, so it can appear (to the threads themselves, and to a human user) that execution is in parallel. If there are multiple processors, or cores, distinct threads may be executed on different processors/cores, and therefore ACTUALLY be executed in parallel.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by Elkvis View Post
    you might consider using std::bind/std::thread or boost::bind/boost::thread instead of raw pthreads function calls.
    I am self-taught, but I want to learn this for something that I am going to be enrolled later and they asked me to use pthreads.
    Quote Originally Posted by grumpy View Post
    That's right.
    Hmm, either you are right or Tech board can be sufficient. Good to know that.

    Quote Originally Posted by grumpy View Post
    Beginners answer: Logically, yeah. That is the point of threads. They keep executing concurrently until they terminate, or until one or more are forced to wait for something. pthread_join() is one way of forcing one thread to wait on another. Synchronisation (e.g. use of mutexes) is another way to force threads to wait on each other.

    Somewhat more technically correct answer: Actually, no. The host operating system and hardware (particularly number of distinct processors, cores) is what determines if threads execute in parallel. Two threads can execute on a single processor, since a component of the host (the scheduler) is responsible for allocating timeslices to each thread, during which the thread can execute some instructions. The scheduler interleaves execution of threads using a series of small timeslices, so it can appear (to the threads themselves, and to a human user) that execution is in parallel. If there are multiple processors, or cores, distinct threads may be executed on different processors/cores, and therefore ACTUALLY be executed in parallel.
    I can modify the hardware from my editor. So, I guess that if my code runs on a system that supports what you are saying, threads will run on parallel.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    2,539
    Quote Originally Posted by std10093 View Post
    So, I guess that if my code runs on a system that supports what you are saying, threads will run on parallel.
    threads may run in parallel. it's conceivable that, even on parallel-capable hardware, the kernel's thread scheduler will still schedule them to run on a single core, and then they won't actually run in parallel.
    Code:
    namespace life
    {
        const bool change = true;
    }

  10. #10
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by Elkvis View Post
    threads may run in parallel. it's conceivable that, even on parallel-capable hardware, the kernel's thread scheduler will still schedule them to run on a single core, and then they won't actually run in parallel.
    I agree. What I am saying, is that my code (by using p_htread_join at that point) will not prevent them from getting executed in parallel (if the system allows it to).
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,527
    pthread_join(), by definition, causes two threads executing in parallel to stop executing in parallel.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  12. #12
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    1,231
    I just open htop in another terminal and then run my code, ensuring that two or more processors are being used. This only works for code that runs long enough to be visually noticed on htop though.

  13. #13
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    I was waiting for the move to be made, so that I could post my thesis on the subject.
    >Beginners answer: Logically, yeah.
    As a beginner I am not yet convinced. Despite the fact that I really want to.

    Assume that our system allows us to run code in parallel. Focus ONLY on what the code I wrote does.

    Let me explain things a bit more analytically.
    I am writting the code in C++ and I have to use pthread. I have to write in C++ too.
    There are two classes, Job and JobListener.
    computePi inherits from Job and its actual word to do is the "Run()" method.
    PiJobListener inherits from JobListener and actually, prints the result the data member of computePi, named Pi, which holds the result of Run() method.
    There is a class Scheduler to schedule all the jobs.
    In main function, there is a loop, something like that:
    Code:
    JobScheduler scheduler();
    for (int i = 0; i < 3; ++i) {
        ComputePi* pi = new ComputePi(100000 * i * i);
        PiJobListener* pi_listener = new PiJobListener();
        scheduler.schedule(pi, pi_listener);
      }
    Then inside Scheduler, I have a vector (named thread), which holds pointers to a class named Task.
    Task class actually has as data members the Job, the JobListener, a pthread and an exit code. I am not sure if I should use the Task class or not.
    The schedule method, does this thread.push_back(new Task(job, listener));
    In the constructor of Task, I do create a thread to execute ComputePi.Run(), then I join the thread (after checking that it was created without errors) and then I call the listener of the job to print the result!
    In the constructor of Task I delete the job, the listener and the task.

    I have the feeling that this way, I do make the code run in serial, because of using pthread_join().
    Here is the code
    Code:
           Task(Job* job_, JobListener* listener_)
    		: job(job_), listener(listener_), exit_code((void*)-1) {
    		int not_ok = pthread_create( &thread, NULL, &Job::RunHelper, job);
                    if(not_ok) std::cout << "Error at creation\n";
    		pthread_join(thread, &exit_code);
      	        listener->handle((int)exit_code, *job);  //print data member of job, i.e. the result
    	}
    If I remove join(), then the handle(), seems to print the data member of job pi, before Run() is done.
    The serial execution of code, as I **believe** it is done.
    Name:  computePiparallel.jpg
Views: 75
Size:  43.4 KB

    I tried to put the join and the listener->handle (which actually is the method that prints the result) in the destructor of Task, by I didn't get any results!
    So, my questions are:
    1)Am I right that I make the code run in serial? If so, is it because join I guess, right?
    2)What happens to a thread created like this: pthread_create( &thread, NULL, &Job::RunHelper, job);
    i.e. with NULL as attribute when it terminates, assuming we haven't called join at any point of it? When it is done, it will "free it self, like detached threads do"?
    3)If I am right and the code is being executed in serial, how should I make it run in parallel?
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  14. #14
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    1. Yes, because of the join.
    2. The thread will not clean up until a join or until the process ends.
    3. You need to start all of your processes first and then call join on them.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  15. #15
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    >2. The thread will not clean up until a join or until the process ends.
    >3. You need to start all of your processes first and then call join on them.
    But some of them will have already completed and end (thus cleaned up) by the time the last one get started!
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-23-2011, 10:00 AM
  2. *szString = things question/memory question
    By Jang in forum C Programming
    Replies: 3
    Last Post: 01-20-2011, 04:59 AM
  3. Newbish Question file reading question....
    By kas2002 in forum C Programming
    Replies: 23
    Last Post: 05-17-2007, 01:06 PM
  4. Self regiserting DLLs question and libraries question.
    By ApocalypticTime in forum Windows Programming
    Replies: 2
    Last Post: 03-22-2003, 02:02 PM
  5. A question of color...(not a racial question)
    By Sebastiani in forum Windows Programming
    Replies: 7
    Last Post: 01-15-2003, 08:05 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21