linux C++ 多线程编程
2015-07-17 15:53
651 查看
转自 : http://blog.chinaunix.net/uid-14880649-id-2954431.html
1.Solaris .vs. Linux Posix 库
如何在linux 下c++中类的成员函数中创建多线程
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;
}
====================================================================================
http://bigbossman.blogbus.com/logs/10761605.html
Linux下的编程一直是C语言的天下,但老是用C感觉写的很乏味。用面向对象方法编程,听着都倍有面子。于是决定先在的这个项目用C++来写。虽然不一定能“以C++的思想”来写C++,少会有C++的样子。
但是问题来了:我需要在程序中动态创建一个线程,而pthread不接受C++类的成员函数作为参数。
原因也很简单,类成员是在类被实例化成为对象后才存在的,即在编译时是不存在的,编译器无法取得函数的确切入口地址,自然无法通过编译。
照这个分析,如果把要调用的类成员函数声明为静态的,pthread_create就可以找到函数的地址了。但这样一来的话,由于类中的静态函数无法调用类的非静态成员。线程函数的功能就受到了很大限制,也就没有比要将其放在类中了。
最容易想到的解决方案就是写个C函数,然后再C函数中调用C++对象的成员函数。
比如类为
class foo(){
public :
thread();
}
class *f;
void *bar(void *arg){
f->thread();
return NULL;
}
int main(){
.........
f=new foo();
pthread_create(&tid,&tattr,bar,NULL);
}
显然这种发法太笨了,而且对象只能是全局的。
注意到线程函数bar可以有一个任意类型的指针作为参数,那我们何不将对象通过这个指针将对象变为bar的一个参数,从而让我们的程序好看一些。
class foo(){
public :
thread();
}
void *bar(void *args){
foo *f=(foo *)args;
f.thread();
return NULL;
}
int main(){
.........
foo *f=new foo();
pthread_create(&tid,&tattr,bar,f);
}
如果把上述两种方法结合起来即对象中的静态函数+通过指针参数传递对象,那又会怎么样呢?
class foo(){
public :
int thread();
static void *wrapper(void *args){
foo *f=static_cast<foo *>(args);
f->thread();
return NULL;
}
}
int main(){
.........
foo *f=new foo();
pthread_create(&tid,&tattr,foo::wrapper,&f);
}
其他参考网页
http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/index.html
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
1.Solaris .vs. Linux Posix 库
Solaris 库(lib 线程) | Linux POSIX 库(libp 线程) | 操作 |
sema_destroy() | sem_destroy() | 销毁信号状态。 |
sema_init() | sem_init() | 初始化信号。 |
sema_post() | sem_post() | 增加信号。 |
sema_wait() | sem_wait() | 阻止信号计数。 |
sema_trywait() | sem_trywait() | 减少信号计数。 |
mutex_destroy() | pthread_mutex_destroy() | 销毁或禁用与互斥对象相关的状态。 |
mutex_init() | pthread_mutex_init() | 初始化互斥变量。 |
mutex_lock() | pthread_mutex_lock() | 锁定互斥对象和块,直到互斥对象被释放。 |
mutex_unlock() | pthread_mutex_unlock() | 释放互斥对象。 |
cond_broadcast() | pthread_cond_broadcast() | 解除对等待条件变量的所有线程的阻塞。 |
cond_destroy() | pthread_cond_destroy() | 销毁与条件变量相关的任何状态。 |
cond_init() | pthread_cond_init() | 初始化条件变量。 |
cond_signal() | pthread_cond_signal() | 解除等待条件变量的下一个线程的阻塞。 |
cond_wait() | pthread_cond_wait() | 阻止条件变量,并在最后释放它。 |
rwlock_init() | pthread_rwlock_init() | 初始化读/写锁。 |
rwlock_destroy() | pthread_rwlock_destroy() | 锁定读/写锁。 |
rw_rdlock() | pthread_rwlock_rdlock() | 读取读/写锁上的锁。 |
rw_wrlock() | pthread_rwlock_wrlock() | 写读/写锁上的锁。 |
rw_unlock() | pthread_rwlock_unlock() | 解除读/写锁。 |
rw_tryrdlock() | pthread_rwlock_tryrdlock() | 读取非阻塞读/写锁上的锁。 |
rw_trywrlock() | pthread_rwlock_trywrlock() | 写非阻塞读/写锁上的锁。 |
如何在linux 下c++中类的成员函数中创建多线程
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;
}
====================================================================================
http://bigbossman.blogbus.com/logs/10761605.html
Linux下的编程一直是C语言的天下,但老是用C感觉写的很乏味。用面向对象方法编程,听着都倍有面子。于是决定先在的这个项目用C++来写。虽然不一定能“以C++的思想”来写C++,少会有C++的样子。
但是问题来了:我需要在程序中动态创建一个线程,而pthread不接受C++类的成员函数作为参数。
原因也很简单,类成员是在类被实例化成为对象后才存在的,即在编译时是不存在的,编译器无法取得函数的确切入口地址,自然无法通过编译。
照这个分析,如果把要调用的类成员函数声明为静态的,pthread_create就可以找到函数的地址了。但这样一来的话,由于类中的静态函数无法调用类的非静态成员。线程函数的功能就受到了很大限制,也就没有比要将其放在类中了。
最容易想到的解决方案就是写个C函数,然后再C函数中调用C++对象的成员函数。
比如类为
class foo(){
public :
thread();
}
class *f;
void *bar(void *arg){
f->thread();
return NULL;
}
int main(){
.........
f=new foo();
pthread_create(&tid,&tattr,bar,NULL);
}
显然这种发法太笨了,而且对象只能是全局的。
注意到线程函数bar可以有一个任意类型的指针作为参数,那我们何不将对象通过这个指针将对象变为bar的一个参数,从而让我们的程序好看一些。
class foo(){
public :
thread();
}
void *bar(void *args){
foo *f=(foo *)args;
f.thread();
return NULL;
}
int main(){
.........
foo *f=new foo();
pthread_create(&tid,&tattr,bar,f);
}
如果把上述两种方法结合起来即对象中的静态函数+通过指针参数传递对象,那又会怎么样呢?
class foo(){
public :
int thread();
static void *wrapper(void *args){
foo *f=static_cast<foo *>(args);
f->thread();
return NULL;
}
}
int main(){
.........
foo *f=new foo();
pthread_create(&tid,&tattr,foo::wrapper,&f);
}
其他参考网页
http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/index.html
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
相关文章推荐
- mysql 在linux上的集群安装方法(数据节点和存储节点分开)
- Linux_Logo – 输出彩色 ANSI Linux 发行版徽标的命令行工具
- linux系统 关闭 oom killer
- linux命令(3)---mkdir
- Centos系统mysql 忘记root用户的密码
- 修改Linux kernel中打印的级别
- centos 挂载与卸载硬盘
- Linux的open函数
- linux sysctl.conf中相关重要设定的详细说明
- linux中内核的一个不错的参数somaxconn
- Linux正则表达式sed
- linux kernel ABC #2 LVM
- CentOS7 配置 vsftpd
- centos下sentinel主从监控配置
- Linux命令学习总结:last
- linux awk、sed、grep
- centos 下Sentinel主从切换
- Linux 使用退格键时出现^H解决方法
- 【cocos2d-x 报错异常集】运行安卓虚拟机的时候出现了emulator: ERROR: Can't find 'Linux version ' string in kernel image fi
- 转 CentOS下面安装RVM+ruby+Rails