std::thread和pthread的区别 及 传递对象指针和引用
引言
朋友突然问我,pthread和std::thread有什么区别?我不知道他为什么会问到这个问题,但是看到问题后我的第一反应是,你是不是C和C++混学的。
区别
pthread
是linux下的多线程API
,头文件为pthread.h
,关于linux线程和进程区别本篇文章略过,因为本文算是给自学人的科普。
std::thread是c++标准库中的线程库,其意义在于可以跨平台不改代码
因为在windows
下创建线程一般会用_beginthreadex
,如果你不想为了linux和windows
同时写2份代码,我相信大多数人的选择都是std::thread
。
这就像是windows
下的Interlocked
和linux
下的__sync
系列函数,c++标准库中同样有实现好的Atomic
类。
其实区别就在于一个使用C语言且是系统公开的API函数,一个是C++标准库中封装的方法,就这么点区别。
std::thread 如何传递对象
举个栗子:
Worker *woker = new Worker();
如果使用std::thread
要用到的是worker中的方法
,且这个方法并不是static方法
,怎么办呢?
关于c++传参问题,如果你不想引起歧义,尽量使用花括号{},原因在这:
Most vexing parse(最烦人的解析)
下面的栗子我们可以看见,新建了一个线程调用
worker
对象的test方法
,但是此时这个方法并不是static
类型,也就是我们不光要传入方法地址
,还要传入worker指针
,test
方法的参数接受一个Number的引用
。
#include <iostream>
#include <thread>
class Number {
private:
int num;
public:
Number() { num = 1; };
explicit Number(int a) :num(a) {}
int getNum() {
return this->num;
}
};
class Worker {
public:
void test(Number& number) {
std::cout << number.getNum() << std::endl;
}
};
int main()
{
Number* number = new Number(99);
Worker* worker = new Worker();
std::thread{ &Worker::test, worker, std::ref(*number) }.join();
delete number;
delete worker;
return 0;
}
test方法明明只有一个参数,为什么我们却在thread第二个参数中传递的是worker指针而不是number的引用?
从代码层面来讲,你可以理解为只有方法地址还不行,还需要传递一个对象指针来确保调用当前类方法时this指针是正确的。
从汇编层面来解释,调用一个非静态类的方法,在进入该类后,其ebp就是对象本身。传递的第一个参数是对象指针的原因就是为了在线程调用这个方法时知道this是谁。
关于std::ref
如果你看过之前的左值右值,你还可以去了解一下完美转发。