概述
文章目录
- 概述
- 1、管理当前线程的函数
- (1).std::this_thread::yield();
- (2).std::thread::id get_id()
- (3).sleep_for
- (4). sleep_until
- 2、管理线程的类型 thread
- (1).构造函数
- (2).拷贝构造函数 和 赋值 operator=
- (3).Move 构造函数 和 Move operator=
- (4). 成员函数
- (5)创建线程,传参
- (5)创建线程,引用传参
- (6).创建建线程,线程函数为类成员函数
- 3、C++多线程获取返回值方法
概述
C++11 引入了 thread 类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的 API,无法解决跨平台问题,代码平台的改变,对应多线程代码也必须要修改。在 C++11 中只需使用语言层面的 thread 可以解决这个问题。编写并发程序需引入头文件<thread>
。
1、管理当前线程的函数
(1).std::this_thread::yield();
可以将本线程的 CPU 时间片放弃,并允许其他线程运行。
① yield 方法其实就是::Sleep(0)。
②Sleep 会交出 CPU 时间片,允许其他线程运行,但“其他线程”也包含了交出 CPU 时间片的那个线程。
③想要更好的进行线程切换,不能够使用 Sleep,而应采用线程锁或其他线程切换方法。
(2).std::thread::id get_id()
获取线程 ID,返回类型 std::thread::id 对象
(3).sleep_for
template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep, Period>& sleep_duration );
阻塞当前线程执行,至少经过指定的 sleep_duration 。此函数可能阻塞长于 sleep_duration ,因为调度或资源争议延迟。
(4). sleep_until
template< class Clock, class Duration >
void sleep_until( const std::chrono::time_point<Clock,Duration>& sleep_time );
阻塞当前线程,直至抵达指定的 sleep_time 。
使用联倾向于 sleep_time 的时钟,这表示时钟调节有影响。从而在调用时间点后,阻塞的时长可能小于,但不会多于 sleep_time - Clock::now() 。函数亦可能阻塞长于抵达 sleep_time 之后,由于调度或资源争议延迟。
2、管理线程的类型 thread
(1).构造函数
①默认构造函数:thread() noexcept
; 一个空的 std::thread 执行对象(无线程执行)
②初始化构造函数
template<class Fn, class... Args>
explicit thread(Fn&& fn, Args&&... args);
创建 std::thread 执行对象,线程调用 threadFun 函数,函数参数为 args。
线程在构造关联的线程对象时立即开始执行,从提供给作为构造函数参数的顶层函数开始(等待任何 OS 调度延迟)。顶层函数的返回值将被忽略,而且若它以抛异常终止,则调用 std::terminate 。
#include<thread>
using namespace std;
void threadFun(int a) // 值传递
{
cout << "this is thread fun !" <<endl;
cout <<" a = "<<a<<endl;
}
int main()
{
thread t1(threadFun, 2);
t1.join(); //等待线程完成其执行
cout<<"Main End "<<endl;
return 0;
}
(2).拷贝构造函数 和 赋值 operator=
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
拷贝构造函数被禁用,std::thread 对象不可拷贝构造,也不可以赋值。
(3).Move 构造函数 和 Move operator=
thread( thread&& other ) noexcept;
thread& operator=( thread&& other ) noexcept;
调用成功原来 other 不再是 std::thread 对象
#include<thread>
using namespace std;
void threadFun(int &a) // 引用传递
{
cout << "this is thread fun !" <<endl;
cout <<" a = "<<(a+=10)<<endl;
}
int main()
{
int x = 10;
thread t1(threadFun, std::ref(x));
thread t2(std::move(t1)); // t1 线程失去所有权
thread t3;
t3 = std::move(t2); // t2 线程失去所有权
//t1.join(); // ?
t3.join();
cout<<"Main End "<<"x = "<<x<<endl;
return 0;
}
(4). 成员函数
①get_id()
:获取线程 ID,返回类型 std::thread::id 对象。
②join()
;创建线程执行线程函数,调用该函数会阻塞当前线程,直到线程执行完 join 才返回。
③detach()
; detach 调用之后,目标线程就成为了守护线程,驻留后台运行,与之关联的 std::thread 对象失去对目标线程的关联,无法再通过 std::thread 对象取得该线程的控制权。
④.joinable()
; 检查 std::thread 对象是否标识活跃(是指该线程的资源没有被释放)的执行线程,不会阻塞线程执行。
⑤swap()
;交换两个线程对象
thread t1(threadFun1);
thread t2(threadFun2);
cout << "线程 1 的 ID:" << t1.get_id() << endl;
cout << "线程 2 的 ID:" << t2.get_id() << endl;
t1.swap(t2);
cout << "线程 1 的 ID:" << t1.get_id() << endl;
cout << "线程 2 的 ID:" << t2.get_id() << endl;
⑥.hardware_concurrency()
; 静态函数,获得逻辑处理器储量,返回值为 int 型
int coreNum = thread::hardware_concurrency();
(5)创建线程,传参
void threadFun(int x)
{
cout << "this is thread fun1 !" << endl;
cout << x << endl;
}
int main()
{
int value = 10;
thread ta(threadFun, value);
ta.join();
getchar();
return 0;
}
需要注意,变量 int value 和 int x 做变量传递时并不是引用,而是对变量做了拷贝,所以在传递给 int x 前,int value 不能出作用域(释放了内存),使用join(),可以保证 int value 变量释放内存,如果使用 detach(),可能存在这种情况
(5)创建线程,引用传参
thread ta(threadFun1, std::ref(value));
(6).创建建线程,线程函数为类成员函数
using namespace std;
class Object
{
private:
int value;
public:
Object(int x = 0):value(x)
{
cout << "Constructor Object: "<<this << endl;
}
~Object()
{
cout << "Destroy Object: "<<this<< endl;
}
void fun(string info)
{
cout << info << value<< endl;
}
};
int main()
{
Object obj;
string str = "我是一个类的成员函数!";
thread t1(&Object::fun, &obj, str);
t1.join();
getchar();
return 0;
}
3、C++多线程获取返回值方法
在线程间共享指针
void func(int x, int y,shared_ptr<int> pa)
{
std::this_thread::sleep_for(std::chrono::seconds(1)); //
*pa = x + y;
}
int main()
{
int x = 10, y = 20;
shared_ptr<int> pa(new int(0)); //使用共享型指针管理释放内存
//thread ta(func,x,y,std::ref(pa));
thread ta(func, x, y,pa);
cout<<"before starting ... *pa: "<<*pa<<endl;
cout<<"Cnt: "<<pa.use_count()<<endl;
ta.join();
cout<<"after joining ... *pa: "<<*pa<<endl;
cout<<"Cnt: "<<pa.use_count()<<endl;
system("pause");
return 0;
}
最后
以上就是文艺石头为你收集整理的c++之thread类概述1、管理当前线程的函数2、管理线程的类型 thread3、C++多线程获取返回值方法的全部内容,希望文章能够帮你解决c++之thread类概述1、管理当前线程的函数2、管理线程的类型 thread3、C++多线程获取返回值方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复