Thread: Multithreading and Class Objects

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    103

    Multithreading and Class Objects

    Hi All

    I am trying to implement multi Threading with class objects.
    I have the requirement to capture details of n students and put in separate file for each student.

    For this I have created some classes and create 4 threads which will do this operation. I am passing class object in pthread_create() function to access various members of class to finish the operation.
    I am using mutex_lock() before function operation starts.

    Below is sample code which I have written.
    Code:
    void *capture1(void *arg)                         
    {                                                 
        int student_count = 0;                                              
        studentCapture *cap = static_cast<studentCapture*>(  arg);                      
        
      while (student_count < 100 )
    {                                              
       pthread_mutex_lock(&count_mutex);     
      cap->validateStudent(temp);              // Operation Function
       cap->initStudentParm(temp);                 // Operation Function
    pthread_mutex_unlock(&count_mutex); 
    student_count++;
    }
                                                      
       
    }
    
    void *capture2(void *arg)                         
    {                                                 
        int student_count = 100;                                              
        studentCapture *cap = static_cast<studentCapture*>(  arg);                      
        
      while (student_count < 1000 )
    {                                              
       pthread_mutex_lock(&count_mutex);     
       cap->validateStudent(temp);              // Operation Function
       cap->initStudentParm(temp);                 // Operation Function
    pthread_mutex_unlock(&count_mutex); 
    student_count++;
    }
                                                      
       
    }
    studentCapture::startCapture()
    {
      rc =  pthread_create(&threads[0], &attr, capture1, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture2, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture3, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture4, (void *)this);
    
    
    }
    There is some more code but I have put relevant one. So my question is, when thread1 is processing initStudentParm() function,after processing validateStudent() function, object will have same specific value regarding that student, which is different from thread 2. But Since object is same and same function of class are in used, will pthread_mutex() feature will help in keeping data correct?

    Is above approach correct?

    Please suggest if anything other will be better.

    Please suggest.

    Thanks
    Nickman

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Are you using a compiler that does not support C++11? If not, then you should be using std::thread instead of pthreads.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Hi

    I am using Iseries and my current version didn;t support C++11. So I have to manage with what I have. I saw tutorial on C++11 multithreading but can't implement on my iseries version.

    Thanks
    Nickman

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    The mutex will ensure that only one thread can operate on the object at once.

    But it won't do anything to control which order the 4 threads will execute in.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Thanks Salem.

    So it mean that if one thread lock mutex say Thread1, then it will execute:
    cap->validateStudent(temp); // Operation Function
    cap->initStudentParm(temp); // Operation Function

    and once the mutex is unlock then Thread2 will take control. This will be fine as each thread will have different student list to process but when one thread is processing, object at that time will have details of student which that thread processing.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by nickman View Post
    So it mean that if one thread lock mutex say Thread1, then it will execute:

    and once the mutex is unlock then Thread2 will take control.
    No, it does not mean that. It is entirely possible that Thread1 will execute fully and terminating before any of the other threads can do any work. Threads by themselves aren't fair. What you can guarantee is that only ONE thread will execute those statements at a time.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Thanks.

    So you mean, thread 1 put mutex lock and while processing functions, Thread 2 will start executing? I was thinking that mutex lock will ensure that untill it is unlock no thread will take control.

    So what should I use? Shemaphores?

    Thanks
    Nickman

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    A typical scenario would be that all 4 threads execute pthread_mutex_lock(&count_mutex); at almost the same time.
    One of them will succeed and go onto cap->validateStudent(temp); and the others will block.

    When the running thread executes pthread_mutex_unlock(&count_mutex); the platform picks some other thread waiting on the mutex and allows it to continue. Which thread executes next is random, but in the long run, each thread will get a fair share of CPU time.


    > So what should I use? Shemaphores?
    I don't know. It might be better to describe your problem rather than us try and reverse engineer the requirement from some broken implementation approach.

    > I was thinking that mutex lock will ensure that untill it is unlock no thread will take control.
    It will, if startCapture() started with pthread_mutex_lock(&count_mutex); before calling all those pthread_creates.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Hi Salem

    You mean code should like be this:

    Code:
    studentCapture::startCapture()
    {
      pthread_mutex_lock(&count_mutex);
      rc =  pthread_create(&threads[0], &attr, capture1, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture2, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture3, (void *)this);
      rc =  pthread_create(&threads[0], &attr, capture4, (void *)this);
     pthread_mutex_unlock(&count_mutex);
     
    }
    As currently I am seeing that with above code, both thread are executing the function.

    Please suggest.

    Thanks
    Nickman

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > As currently I am seeing that with above code, both thread are executing the function.
    What did you expect?

    If you wanted capture1 to run to completion, then capture2 to run to completion, then why are you even messing about with threads?

    If you want this behaviour with threads, then you need a different approach.

    Works for me
    Code:
    #include <iostream>
    #include <pthread.h>
    
    using namespace std;
    
    pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
    
    class Student
    {
    public:
      Student() : last(0) { }
      
      static void *capture1(void *arg) {
        Student *cap = static_cast<Student*>(arg);
        for ( int i = 0 ; i < 10000 ; i++ ) {
          pthread_mutex_lock(&count_mutex);
          cap->dowork(i);
          pthread_mutex_unlock(&count_mutex);
        }
        return NULL;
      }
      static void *capture2(void *arg) {
        Student *cap = static_cast<Student*>(arg);
        for ( int i = 0 ; i < 10000 ; i++ ) {
          pthread_mutex_lock(&count_mutex);
          cap->dowork(i);
          pthread_mutex_unlock(&count_mutex);
        }
        return NULL;
      }
      static void *capture3(void *arg) {
        Student *cap = static_cast<Student*>(arg);
        for ( int i = 0 ; i < 10000 ; i++ ) {
          pthread_mutex_lock(&count_mutex);
          cap->dowork(i);
          pthread_mutex_unlock(&count_mutex);
        }
        return NULL;
      }
      static void *capture4(void *arg) {
        Student *cap = static_cast<Student*>(arg);
        for ( int i = 0 ; i < 10000 ; i++ ) {
          pthread_mutex_lock(&count_mutex);
          cap->dowork(i);
          pthread_mutex_unlock(&count_mutex);
        }
        return NULL;
      }
      void dowork(int i) {
        if ( last != pthread_self() ) {
          cout << "Worker " << this 
               << " on thread " << pthread_self() 
               << " resumed at " << i << endl;
          last = pthread_self();
        }
      }
      void start() {
        int rc;
        pthread_mutex_lock(&count_mutex);
        pthread_attr_t attr;
        cout << "Creating threads....";
        pthread_attr_init(&attr);
        rc =  pthread_create(&threads[0], &attr, capture1, (void *)this);
        rc =  pthread_create(&threads[1], &attr, capture2, (void *)this);
        rc =  pthread_create(&threads[2], &attr, capture3, (void *)this);
        rc =  pthread_create(&threads[3], &attr, capture4, (void *)this);
        pthread_attr_destroy(&attr);
        cout << "done" << endl;
        pthread_mutex_unlock(&count_mutex);
      }
      void end() {
        void *res;
        pthread_join(threads[0],&res);
        pthread_join(threads[1],&res);
        pthread_join(threads[2],&res);
        pthread_join(threads[3],&res);
      }
    private:
      pthread_t threads[4];
      pthread_t last;
    };
    
    int main ( ) {
      Student s;
      cout << "Main Start" << endl;
      s.start();  // sow
      s.end();    // reap
      cout << "Main End" << endl;
    }
    
    
    $ g++ foo.cpp -pthread
    $ ./a.out 
    Main Start
    Creating threads....done
    Worker 0x7fff037a2980 on thread 140706368927488 resumed at 0
    Worker 0x7fff037a2980 on thread 140706377320192 resumed at 0
    Worker 0x7fff037a2980 on thread 140706352142080 resumed at 0
    Worker 0x7fff037a2980 on thread 140706368927488 resumed at 755
    Worker 0x7fff037a2980 on thread 140706360534784 resumed at 0
    Worker 0x7fff037a2980 on thread 140706368927488 resumed at 927
    Worker 0x7fff037a2980 on thread 140706360534784 resumed at 142
    Worker 0x7fff037a2980 on thread 140706352142080 resumed at 185
    Worker 0x7fff037a2980 on thread 140706360534784 resumed at 143
    Worker 0x7fff037a2980 on thread 140706352142080 resumed at 356
    Worker 0x7fff037a2980 on thread 140706377320192 resumed at 210
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Hi Salem

    My Concern was on object.Since both the thread are using same object, one thread can overide the other object content.

    I got an idea to create 4 objects and pass them to capture1,capture2,capture3 and capture4. So in this way each thread will have each independent object and no overriding and process will run fast.

    Is that sound good?

    Thanks
    Nickman

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Sure, if they're independent objects, then there is little need for a mutex is there.

    But all your examples have been 4 instances of 'this' as the data parameter to pthread_create.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    I'll change it and then test.

    Thanks for advice. Will get back if see any issue.

    Thanks
    Nickman

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 01-06-2015, 09:04 AM
  2. Hi, about Class and Objects
    By student111 in forum C++ Programming
    Replies: 1
    Last Post: 01-10-2012, 02:20 PM
  3. Replies: 3
    Last Post: 07-15-2010, 07:53 PM
  4. Replies: 4
    Last Post: 10-16-2003, 11:26 AM
  5. base class pointer to derived class objects
    By curlious in forum C++ Programming
    Replies: 4
    Last Post: 09-28-2003, 08:39 PM