如何在linux 下c++中类的成员函数中创建多线程
2012-05-29 21:32
337 查看
linux系统中线程程序库是POSIX pthread。POSIX pthread它是一个c的库,用C语言进行多线程编程我这里就不多说了,网上的例子很多。但是如何在C++的类中实现多线程编程呢?如果套用C语言中创 建多线程的方式,在编译的时候会出现...does not match `void*(*)(void*)..这样的错误。出现这种情况的原因是,编译器在处理C++和C文件上是不同的,也就是说C++和C语言里边指针函数不 等价。解决这种错误的方法
有两种:
1、不要将线程函数定义为类的成员函数,但是在类的成员函数里边调用它。
例如:
[test.h]
#ifndef TEST_H
#define TEST_H
class test
{
public:
test();
~test();
private:
void createThread();
};
#endif
[test.cpp]
test::test()
{}
test::~test()
{}
void *threadFunction()
{
printf("This is a thread");
for(;;);
}
void test::createThread()
{
pthread_t threadID;
pthread_create(&threadID, NULL, threadFunction, NULL);
}
[main.cpp]
#inlcude "test.h"
int main()
{
test t;
t.createThead();
for(;;);
return 0;
}
2、将线程函数作为类的成员函数,那么必须声明改线程函数为静态的函数,并且该线程函数所引用的其他成员函数也必须是静态的,如果要使用类的成员变量,则必须在创建线程的时候通过void *指针进行传递。
例如:
【test.h】
#ifndef TEST_H
#define TEST_H
class test
{
public:
test();
~test();
private:
int p;
static void *threadFction(void *arg);
static void sayHello(int r);
void createThread();
};
#endif
[test.cpp]
test::test()
{}
test::~test()
{}
void *test::threadFunction(void *arg)
{
int m = *(int *)arg;
sayHello(m);
for(;;);
}
void sayHello(int r)
{
printf("Hello world %d!\n", r);
}
void test::createThread()
{
pthread_t threadID;
pthread_create(&threadID, NULL, threadFunction, NULL);
}
[main.cpp]
#inlcude "test.h"
int main()
{
test t;
t.createThead();
for(;;);
return 0;
}
/************************************************************************************************************************************************************************************/
总结了:
原因:
类里的非静态函数函数地址是不固定的;
pthread_create中需指定线程地址,因此怎么改都错;
类的成员函数,不能转换成void (*)(void *)类型。
解决:
1.把线程函数定义成类的静态函数。同时不能访问类的非静态成员变量,并且所有类的实例都有共同的该成员函数,对于NS中模拟300个该类的节点对象,并不太适合:)
2.把线程函数不定义成类成员函数,而是一个公共的函数,并且声明为该类的友员,否则无法访问类的非公有变量
A.把函数定义为普通的全局函数,此时启动线程时可能会传参,如果传递的是this指针,则此方法不可行,因为C* 无法转换为void*
B.把函数定义为静态的全局函数,其参数形式为void* func(void* arg), 启动语句为pthread_create(&id, NULL,func,this),在func内部实现类型转换C* agent = static_cast(arg);
class *th = (class *)pvoid;
/************************************************************************************************************************************************************************************/
本人参照上面,在代码中修改解决该问题:
定义waitwork为全局函数 void* waitWork(void* arg);
在类成员函数addwork()中 void CHttpSerWorker::addWork()。
int iRet = pthread_create(&th, NULL, waitWork, this);//传入this
在waitwork函数中将this转化:CHttpSerWorker *hsw=(CHttpSerWorker *)arg;
有两种:
1、不要将线程函数定义为类的成员函数,但是在类的成员函数里边调用它。
例如:
[test.h]
#ifndef TEST_H
#define TEST_H
class test
{
public:
test();
~test();
private:
void createThread();
};
#endif
[test.cpp]
test::test()
{}
test::~test()
{}
void *threadFunction()
{
printf("This is a thread");
for(;;);
}
void test::createThread()
{
pthread_t threadID;
pthread_create(&threadID, NULL, threadFunction, NULL);
}
[main.cpp]
#inlcude "test.h"
int main()
{
test t;
t.createThead();
for(;;);
return 0;
}
2、将线程函数作为类的成员函数,那么必须声明改线程函数为静态的函数,并且该线程函数所引用的其他成员函数也必须是静态的,如果要使用类的成员变量,则必须在创建线程的时候通过void *指针进行传递。
例如:
【test.h】
#ifndef TEST_H
#define TEST_H
class test
{
public:
test();
~test();
private:
int p;
static void *threadFction(void *arg);
static void sayHello(int r);
void createThread();
};
#endif
[test.cpp]
test::test()
{}
test::~test()
{}
void *test::threadFunction(void *arg)
{
int m = *(int *)arg;
sayHello(m);
for(;;);
}
void sayHello(int r)
{
printf("Hello world %d!\n", r);
}
void test::createThread()
{
pthread_t threadID;
pthread_create(&threadID, NULL, threadFunction, NULL);
}
[main.cpp]
#inlcude "test.h"
int main()
{
test t;
t.createThead();
for(;;);
return 0;
}
/************************************************************************************************************************************************************************************/
总结了:
原因:
类里的非静态函数函数地址是不固定的;
pthread_create中需指定线程地址,因此怎么改都错;
类的成员函数,不能转换成void (*)(void *)类型。
解决:
1.把线程函数定义成类的静态函数。同时不能访问类的非静态成员变量,并且所有类的实例都有共同的该成员函数,对于NS中模拟300个该类的节点对象,并不太适合:)
2.把线程函数不定义成类成员函数,而是一个公共的函数,并且声明为该类的友员,否则无法访问类的非公有变量
A.把函数定义为普通的全局函数,此时启动线程时可能会传参,如果传递的是this指针,则此方法不可行,因为C* 无法转换为void*
B.把函数定义为静态的全局函数,其参数形式为void* func(void* arg), 启动语句为pthread_create(&id, NULL,func,this),在func内部实现类型转换C* agent = static_cast(arg);
class *th = (class *)pvoid;
/************************************************************************************************************************************************************************************/
本人参照上面,在代码中修改解决该问题:
定义waitwork为全局函数 void* waitWork(void* arg);
在类成员函数addwork()中 void CHttpSerWorker::addWork()。
int iRet = pthread_create(&th, NULL, waitWork, this);//传入this
在waitwork函数中将this转化:CHttpSerWorker *hsw=(CHttpSerWorker *)arg;
相关文章推荐
- 如何在linux 下c++中类的成员函数中创建多线程
- linux下 C++如何实现多线程
- linux下 C++如何实现多线程
- [C++ 2011 多线程系列一]如何创建线程
- C++ Linux 多线程之创建、管理线程
- 初学者如何在 Linux (Ubuntu) 下搭建C/C++ 开发环境
- c++ 多线程编程之创建新线程
- 如何创建Linux Initrd
- 如何快速在Linux系统的硬盘上创建大文件
- Linux下如何批量创建用户并设置8位随机密码
- 如何在Linux命令行中创建以及展示演示稿
- 如何为Red Hat Linux创建分区?
- linux下多线程的创建与等待详解
- linux下如何编译c++工程项目
- 关于如何在make一个Linux下的C/C++工程时,自动添加版本号、编译日期等信息
- 如何在Linux下创建与解压zip, tar, tar.gz和tar.bz2文件
- reinstall_xbt: Linux中如何查看文件的最初创建时间
- 如何在Linux使用Eclipse + CDT开发C/C++程序?
- Linux下如何创建loop device
- linux杂谈(八):如何手动的去创建一个linux用户