#include <pthread.h>
int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
void *(*start_routine)(void*), void *arg);
以上是 pthread_create()
的声明。
但是在学习《Linux高性能服务器编程》,实现线程池的时候,发现有这么一句话
类内使用 pthread_create 函数时,将函数的第 3 个参数指向一个静态函数(必须是静态函数)。
百思不得其解,遂查了一部分资料得到以下解答:
在类内调用 pthread_create
,并且想要将成员函数作为参数的时候,实际传参过程中,还会传递 this
指针(就这儿)
If you are rusty on your C++, let me remind you of the problem. Every C++ member function has a hidden first passed parameter known as the this parameter. Via the this parameter, the function knows which instance of the class to operate upon. Because you never see these this parameters, it is easy to forget they exist.
Now, let’s again consider the _beginthread() function which allows us to specify an arbitrary entry-point-function for our new thread. This entry-point-function must accept a single void* passed param. Aye, there’s the rub. The function signature required by _beginthread() does not allow the hidden this parameter, and hence a C++ member function cannot be directly activated by _beginthread().
C++类中的成员函数其实默认在参数中包含有一个this指针,这样成员函数才知道应该对哪个实例作用。而线程函数必须接受一个void指针作为参数,所以导致了矛盾。为了解决矛盾,我们可以使用static函数,它独立于实例,参数中将不会有this指针,所以可以用于打开线程。
所以我们需要传入的成员函数应该是 static
静态成员函数,但是怎么调用类内其他的方法呢?
有两种方法
《Linux高性能服务器编程》
- 通过类的静态对象来调用。比如单例模式中,静态函数可以通过类的全局唯一实例了来访问动态成员函数。
- 将类的对象作为参数传递给该静态函数,然后在静态函数中引用这个对象,并调用其动态方法。
线程池中使用的便是第二种方法
static void* worker( void* arg );
pthread_create( m_threads + i, NULL, worker, this )