C++中类成员函数被当作thread入参时注意点

1. pthread_create与std::thread

pthread_create:

void *(*start_routine) (void *) 注意入参的类型

       #include 

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       Compile and link with -pthread.

std::thread:

  template<typename _Callable, typename... _Args>
      explicit
      thread(_Callable&& __f, _Args&&... __args)
      {
#ifdef GTHR_ACTIVE_PROXY
	// Create a reference to pthread_create, not just the gthr weak symbol.
	auto __depend = reinterpret_cast<void(*)()>(&pthread_create);
#else
	auto __depend = nullptr;
#endif
        _M_start_thread(_S_make_state(
	      __make_invoker(std::forward<_Callable>(__f),
			     std::forward<_Args>(__args)...)),
	    __depend);
      }
  1. 默认构造函数 thread() noexcept;
  2. 初始化构造函数 template
  3. explicit thread(Fn&& fn, Args&&… args);
  4. 拷贝构造函数 [deleted] thread(const thread&) = delete; 不能拷贝
  5. Move 构造函数 thread(thread&& x) noexcept;

2. 问题出现

#include 
#include 
#include 
 #include 
class Wrapper {
  public:

      void member1() {
          std::cout << "i am member1" << std::endl;
      }
      void member2(const char *arg1, unsigned arg2) {
          std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
      }
     void  member1Thread() {
          //pthread_create(&pd,NULL,member1, this);  //问题来了,直接调用成员函数,导致error
          pthread_create(&pd,NULL,&Wrapper::member1, this);  //依然出错
      }
      std::thread member2Thread(const char *arg1, unsigned arg2) {
          return std::thread(&Wrapper::member2, this, arg1, arg2);
      }
      pthread_t pd;
};

int main() {
  Wrapper *w = new Wrapper();
   w->member1Thread();
  pthread_join(w->pd,NULL);
  w->member2Thread("hello", 100).detach();
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0; }
thread1.cpp:16:57: error: cannot convert ‘void (Wrapper::*)()’ to ‘void* (*)(void*)for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)pthread_create(&pd,NULL,&Wrapper::member1, this); 

pthread_create需要的参数类型为void * (* )(void*),而member1作为类的成员函数时其类型是void* (Wrapper :: )(Wrapper*)的成员函数指针,不能直接转换。

3. 解决问题

注意使用成员函数当入参时,要这样写&Wrapper::member1

3.1 使用静态成员函数,传入this,再通过该指针调用函数

#include 
#include 
#include 
 #include 
class Wrapper {
  public:

    static void* newfun(void* t)
    {
        Wrapper* wp = static_cast<Wrapper*>(t);
        wp->member1();
        return NULL ;
    }
      void member1() {
          std::cout << "i am member1" << std::endl;
      }
      void member2(const char *arg1, unsigned arg2) {
          std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
      }
     void  member1Thread() {
          pthread_create(&pd,NULL,newfun, this);
      }
      std::thread member2Thread(const char *arg1, unsigned arg2) {
          return std::thread(&Wrapper::member2, this, arg1, arg2);
      }
      pthread_t pd;
};

int main() {
  Wrapper *w = new Wrapper();
   w->member1Thread();
  pthread_join(w->pd,NULL);
  w->member2Thread("hello", 100).detach();
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0; }

3.2 使用指针强制类型转换

#include 
#include 
#include 
 #include 
class Wrapper {
  public:
      void member1() {
          std::cout << "i am member1" << std::endl;
      }
      void member2(const char *arg1, unsigned arg2) {
          std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
      }
     void  member1Thread() {
          pthread_create(&pd,NULL,reinterpret_cast<void*(*)(void*)>(&Wrapper::member1), this);
      }
      std::thread member2Thread(const char *arg1, unsigned arg2) {
          return std::thread(&Wrapper::member2, this, arg1, arg2);
      }
      pthread_t pd;
};

int main() {
  Wrapper *w = new Wrapper();
   w->member1Thread();
  pthread_join(w->pd,NULL);
  w->member2Thread("hello", 100).detach();
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0; }

3.3 使用std::thread

#include 
#include 
#include 
class Wrapper {
  public:
      void member1() {
          std::cout << "i am member1" << std::endl;
      }
      void member2(const char *arg1, unsigned arg2) {
          std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
      }
      std::thread member1Thread() {
          return std::thread(&Wrapper::member1, this);
      }
      std::thread member2Thread(const char *arg1, unsigned arg2) {
          return std::thread(&Wrapper::member2, this, arg1, arg2);
      }
};

int main() {
  Wrapper *w = new Wrapper();
  std::thread tw1 = w->member1Thread();
  tw1.join();
  w->member2Thread("hello", 100).detach();
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  return 0; }
lxz@lxz-VirtualBox:~/liuxz/mymuduo/muduo_code/mydemo/thread_1$ ./main 
i am member1
i am member2 and my first arg is (hello) and second arg is (100)

你可能感兴趣的:(c++学习,服务端编程)