当线程函数为C++类成员函数时
来源:互联网 发布:西门子工控软件 编辑:程序博客网 时间:2024/05/11 04:14
很多时候我们在C++多线程开发时,都会或多或少遇到线程函数为C++类中的某个成员函数,此时可能会发生什么呢?你有可能会杂么做呢?
接下来我就为大家总结一下我在这方面走过的一个历程
1.问题一
记得我在之前在写一个udp传输文件的程序时,我就第一次遇到了线程函数为C++类的成员函数,当时遇到的问题,大概意思如下:
#include<iostream>#include <thread>#include <unistd.h>class Test{ public: Test():testThread_(print) { } void print(void) { std::cout<<"hello"<<std::endl; } private: std::thread testThread_;};int main(int argc,char **argv){ Test test; sleep(1000); 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
如上述代码,当我编译时会产生如下编译结果
根据第一个error报错,貌似程序希望我们把print函数设为静态函数,第二个error则意思是我们传递的参数不能和std::thread所匹配。我的前几篇博文有写过std::thread相关的知识,它的第一个参数为函数指针,而我们的标准C++里这样是获取不到其成员函数的指针的所以才会产生上述的报错。关于C++获取其成员函数方面的知识,请参考这个链接http://www.zhihu.com/question/27738023
2.(一)解决方案
根据一种的报错,我想我们想到的最简单的方法就是把成员函数设成静态成员函数
具体如下
#include<iostream>#include <thread>#include <unistd.h>class Test{ public: Test():testThread_(print) { } static void print(void) { std::cout<<"hello"<<std::endl; } private: std::thread testThread_;};int main(int argc,char **argv){ Test test; sleep(1000); 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
这个代码解决了我在一中遇到的问题
3.问题二
2中似乎表面上解决了我的问题,但事实上由于2的解决方案,我又遇到了新的问题
#include<iostream>#include <thread>#include <unistd.h>class Test{ public: Test(int m):n(m),testThread_(print) { } static void print(void) { std::cout<<n<<std::endl; } private: int n; std::thread testThread_;};int main(int argc,char **argv){ Test test(8); sleep(1000); 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
在上述代码中,当我的线程函数在使用类的成员函数时,编译时会报错
这是因为,我们的静态成员函数并不能使用非静态的成员变量(因为它没有某个具体对象的this指针)
4.(二)解决方案1
解决方案很简单,我们只需给静态成员函数传递某对象的this指针即可
具体如下
#include<iostream>#include <thread>#include <unistd.h>class Test{ public: Test(int m):n(m),testThread_(print,this) { } static void print(Test *pt) { std::cout<<pt->n<<std::endl; } private: int n; std::thread testThread_;};int main(int argc,char **argv){ Test test(8); sleep(1000); 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
5.(二)解决方案2
4中的确完全解决了我们在线程中调用类的成员函数的所有问题,但是你会不会感觉其用起来很别扭,本来我们只是向使一个成员函数为线程函数,这样我们就可以在该线程函数中直接使用该类的成员变量了,但是由于2中有叙述的那些原因,结果使我们不得不使用将成员函数设为静态的,结果就是我们现在使用类的成员变量会这么麻烦,感觉好不爽。难道就没什么方法可以让我们不是成员函数变为静态的?
哈哈,当然是有的具体方案如下
#include<iostream>#include <thread>#include <unistd.h>#include <functional>class Test{ public: Test(int m):n(m),testThread_(std::bind(&Test::print,this)) { } void print(void) { std::cout<<n<<std::endl; } private: int n; std::thread testThread_;};int main(int argc,char **argv){ Test test(8); sleep(1000); 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
我们可以像上述代码那样只需用C++11新标准的std::bind函数将其成员函数与对应的对象指针(即this指针)绑定之后便可高枕无忧的解决我们上述的所有问题了
- 当线程函数为C++类成员函数时
- 当线程函数为C++类成员函数时
- 直接使用类成员函数为线程函数
- C++使用线程函数pthread_create时,调用的成员函数要定义为静态成员函数
- C++中 线程函数为静态函数 及 类成员函数作为回调函数
- 类成员函数创建线程
- 类成员函数创建线程
- 类的成员函数与线程函数
- 线程创建函数与类成员函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 类成员函数作为线程函数
- 线程函数和类成员函数
- 解决phpstorm运行很卡问题!
- leetcode--88. Merge Sorted Array
- GET POST 浅谈
- ConcurrentHashMap
- 科学研究设计一:什么是科学
- 当线程函数为C++类成员函数时
- servlet中请求转发(forword)与重定向(sendredirect)的区别
- 指针
- 获取Android手机的屏幕分辨率
- JavaSE基础部分易错点_01
- png、jpg、gif与webp不得不说的前端基础知识
- vim复制的时候格式出错
- 正则表达式
- linux安装mysql5.7.20步骤