C++中的 多线程

来源:互联网 发布:2012nba总决赛球员数据 编辑:程序博客网 时间:2024/06/08 03:21

有很多时候,我们希望可以在C++类里面对那些比较耗时的函数使用多线程技术,但是熟悉C++对象语法的人应该知道,C++类的成员函数的函数指针不能直接做为参数传到pthread_create,主要因为是C++成员函数指针带有类命名空间,同时成员函数末尾是会被C++编译器加上可以接收对象地址的this指针参数。因此需要将成员函数做一定的转化,将其转化为不被编译器加上this指针,而由我们自己来为该函数维护”this”指针即可。

举例分析

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <time.h>using namespace std;class Test{    public:        int sum=0;        int cnt;    public:        int insert();};int Test::insert(){    sleep(2);    cnt+=1;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

如上所示,代码声明了一个类Test,假设该类有一个十分耗时的成员函数:insert(),这个求和函数每次执行需要2000ms的时间。对于如此耗时的函数,我们在设计时都会想方法将其设计为线程函数,这样调用者才不会阻塞。 
于是我们为其加上多线程:

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <time.h>#include <unistd.h>#include <pthread.h>using namespace std;class Test{    public:        int sum=0;        int cnt;    public:        int insert();        void * insert_pth(void*);        void lanch();};int Test::insert(){    sleep(2);    sum+=1;}void * Test::insert_pth(void*){    insert();}void Test::lanch(){    pthread_t pth;    pthread_create(&pth,NULL,insert_pth,NULL);}int main(){    Test t;    t.lanch();    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

以上代码通过调用lanch()来创建多线程来执行insert_pth,insert_pth 再调用insert(). 
但是 这样的代码在编译时即会报错。

pthread.cpp: In member functionvoid Test::lanch()’:pthread.cpp:30:42: error: invalid use of non-static member function  pthread_create(&pth,NULL,insert_pth,NULL);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

只需将insert_pth变化为static函数,同时将insert逻辑代码转移到insert_pth即可

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <time.h>#include <unistd.h>#include <pthread.h>using namespace std;class Test{    public:        int sum=0;        int cnt;    public:        int insert();    static  void * insert_pth(void*);        void lanch();};int Test::insert(){    sleep(2);    sum+=1;    printf("%d insert.....\n",sum);}void * Test::insert_pth(void* __this){    Test * _this =(Test *)__this;    sleep(2);    _this->sum+=1;    printf("%d insert.....\n",_this->sum);}void Test::lanch(){    pthread_t pth;    pthread_create(&pth,NULL,insert_pth,(void*)this);}int main(){    Test t;    t.sum=0;    t.lanch();    sleep(5);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

总结

使用多线程处理耗时成员函数的步骤: 
1. 声明另外一个静态函数:static void XXX_pth(void __this); 
该函数与目标成员函数在函数名尽量保持一致 
2. 将原成员函数的代码拷贝至void * XXX_pth(void * __this); 
在 XXX_pth()开始处将void * __this 转化为 对象的指针 ObjectPoint _this; 
将拷贝下来的所有成员变量加上_this-> 
3. 编写线程启动代码。 
注意pthread_create()最后一个参数传入this指针

注意

在 XXX_pth()函数内容不要调用类的其它成员函数,否则成员函数将无法获取正确的this指针而操作错误内存,从而导致segmantation fault.
原创粉丝点击