pthread in a class

2019-06-21 23:13发布

问题:

Hey everyone, considering the following code (compiled with g++ -lpthread thread_test.cpp) how can I know what number thread I am in from inside "thread_function"? And let me know if you have any other suggestions.

Thanks!

thread_test.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

class A { 
   public:
      A();
      void run();

   private:
      static void* thread_function( void *ptr );
      pthread_t m_thread1, m_thread2;

      static int m_global;
};

int A::m_global = 0;

A::A() {
   int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
   int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}

void A::run() {
   while ( 1 ) { 
      printf( "parent incrementing...\n" );
      m_global++;
      sleep( 2 );
   }   
}

void* A::thread_function( void *ptr ) { 
   printf( "I'm thread ?\n" );

   while ( 1 ) { 
      printf("thread global: %d\n", m_global );
      sleep( 1 );
   }   
}

int main() {
   A a;
   a.run();

   return 0;
}

回答1:

You can use pthread_self() function.



回答2:

Well i figured out I could do this, but I'm not sure if making the pthread_t variables static is the best thing to do. Opinions?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

class A { 
   public:
      A();
      void run();

   private:
      static void* thread_function( void *ptr );
      static pthread_t m_thread1, m_thread2;

      static int m_global;
};

int A::m_global = 0;
pthread_t A::m_thread1 = 0;
pthread_t A::m_thread2 = 0;

A::A() {
   int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
   int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}

void A::run() {
   while ( 1 ) { 
      printf( "parent incrementing...\n" );
      m_global++;
      sleep( 2 );
   }   
}

void* A::thread_function( void *ptr ) { 
    int thread_num = 0;
    if ( pthread_self() == m_thread1 ) {
        thread_num = 1;
    } else {
        thread_num = 2;
    }

    printf( "I'm thread %d\n", thread_num );

    while ( 1 ) { 
        printf("thread %d global: %d\n", thread_num, m_global );
        sleep( 1 );
    }   
}

int main() {
   A a;
   a.run();

   return 0;
}


回答3:

The correct answer depends heavily on why you need this information. If the two threads are doing different things, why do they have the same start function?

One simple fix is this:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

class A { 
   public:
      A();
      void run();

   private:
      static void* thread_function( void *ptr, int which );
      static void* thread_function_1( void *ptr );
      static void* thread_function_2( void *ptr );
      pthread_t m_thread1, m_thread2;

      static int m_global;
};

int A::m_global = 0;

A::A() {
   int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function_1, this );
   int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function_2, this );
}

void A::run() {
   while ( 1 ) { 
      printf( "parent incrementing...\n" );
      m_global++;
      sleep( 2 );
   }   
}

void* A::thread_function_1( void *ptr ) { thread_function(ptr, 1); }
void* A::thread_function_2( void *ptr ) { thread_function(ptr, 2); }

void* A::thread_function( void *ptr, int which ) { 
   printf( "I'm thread %d\n", which );

   while ( 1 ) { 
      printf("thread global: %d\n", m_global );
      sleep( 1 );
   }   
}

int main() {
   A a;
   a.run();

   return 0;
}

If you have more than 2 threads, you can use another approach. Create a structure that holds all the information the thread needs, including the this pointer and which thread it is. Allocate a structure of that type, stuff it with everything the thread needs and pass that to the thread through the pthread_create function instead of just the this pointer.