0

我在从单例类中线程化非静态方法时遇到问题,请查看代码:

//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;
}

如您所见KerryRayKing(),它是静态的,不像JeffHanneman(). 我未能通过JeffHanneman()pthread_create()在编译时我得到:

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

我尝试了几次演员,但失败了......不可能在这种情况下使用非静态方法吗?

编辑 :

我忘了说,我不想允许JeffHanneman()从外部访问

4

1 回答 1

4

简短的回答:你不能那样做。

有几种解决方法,最简单的是具有static包装功能,例如

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);
};

现在,pthread create 变为:

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

[我避免使用“JHRapper”的双关语,因为我认为那会相当贬低......]

于 2013-06-16T19:34:16.627 回答