1. pthread_create与std::thread
pthread_create:
void *(*start_routine) (void *) 注意入参的类型
#include <pthread.h>
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);
}
- 默认构造函数 thread() noexcept;
- 初始化构造函数 template <class Fn, class… Args>
- explicit thread(Fn&& fn, Args&&… args);
- 拷贝构造函数 [deleted] thread(const thread&) = delete; 不能拷贝
- Move 构造函数 thread(thread&& x) noexcept;
2. 问题出现
#include <thread>
#include <iostream>
#include <pthread.h>
#include <chrono>
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 <thread>
#include <iostream>
#include <pthread.h>
#include <chrono>
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 <thread>
#include <iostream>
#include <pthread.h>
#include <chrono>
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 <thread>
#include <iostream>
#include <chrono>
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)