简体   繁体   中英

C++, linux, how to pass a not static method from a singleton to pthread_create?

I have a problem with threading a not static method from a singleton class,look at the code :

//g++ main.cc -lpthread
#include<iostream>
#include<unistd.h>                 
#include<pthread.h>

class SLAYER{
  private:
    SLAYER(){};
    ~SLAYER(){};
    static SLAYER *singleton;
    pthread_t t1, t2;

  public: 
    static void *born(){
      singleton = new SLAYER;
    };
    static void *death(){
      delete singleton;
      singleton = NULL;
    };
    static void *start(){
      pthread_create(&singleton->t1,NULL,singleton->KerryRayKing, NULL);
      pthread_create(&singleton->t2,NULL,singleton->JeffHanneman, NULL);
    };
    void *JeffHanneman(void *arg){
      sleep(1);
      std::cout << "(1964-2013) R.I.P.\n";
      (void) arg;
      pthread_exit(NULL);
    };
    static void *KerryRayKing(void *arg){
      sleep(1);
      std::cout << "(1964-still with us) bald\n";
      (void) arg;
      pthread_exit(NULL);
    };
};

SLAYER *SLAYER::singleton=NULL;

int main(){
  SLAYER::born();
  SLAYER::start();
  std::cout << "thread started\n";
  sleep(5);
  SLAYER::death();
  return 0;
}

as you can see KerryRayKing() is static unlike JeffHanneman() . I failed to pass JeffHanneman() to pthread_create() , at compilation time I got :

cannot convert ‘SLAYER::JeffHanneman’ from type ‘void* (SLAYER::)(void*)’ to type ‘void* (*)(void*)’

I tried several cast, but failed... isn't possible to use in this cas a non static method ?

edit :

I forgot to say, I don't want to allow access to JeffHanneman() from outside

Short answer: you can't do that.

There are several workarounds, the simplest is to have static wrapper function, eg

static void *JHWrapper(void *self)
{
   SLAYER *that = static_cast<SLAYER*>(self);
   return that->JeffHanneman(); 
}

void *JeffHanneman(){   // Note "arg" removed.
  sleep(1);
  std::cout << "(1964-2013) R.I.P.\n";
  pthread_exit(NULL);
};

Now, the pthread create becomes:

 pthread_create(&singleton->t1,NULL, SLAYER::JHWrapper, static_cast<void *>(singleton));

[I refrained from the pun of "JHRapper", as I think that would be rather demeaning...]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM