C++中std::thread线程用法

目录
  • 1:std::thread的基本用法
  • 2:std:: thread常用的成员函数
  • 3:建立新 thread执行类别中的函数
  • 4:建立新 thread 执行 lambda expression
  • 5:join等待thread执行结束
  • 6:detach不等待 thread执行结束
  • 7:std::thread 参数传递使用引用的方法

1:std::thread的基本用法

最简单的 std::thread用法如下,调用 thread将立即同时开始执行这个新建立的线程,新线程的任务执行完毕之后, main()的主线程也会继续执行。

#include<iostream>
#include<thread>
#include<windows.h>
#include<string>
using namespace std;

void myfunc_work() {
	cout << "myfunc_work ....." << endl;
	// do something 5s
	Sleep(5000);
}

int main() {
	std::thread t1(myfunc_work);
	// 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑
	t1.join();
	cout << "main thread ....." << endl;

}

2:std:: thread常用的成员函数

下面为C++  std::thread常用的成员函数

get_id()    取得目前的线程 id, 回传一个 std::thread::id  类型

joinable()    检查是否可 join

join()   // 阻塞当前线程,等待子线程执行完毕

detach()  // 与该线程分离,一旦该线程执行完后它所分配的资源就会被释放

native_handle()    取得平台原生的 native handle.

sleep_for()    // 停止目前线程一段指定的时间

yield()   // 暂时放弃CPU一段时间,让给其他线程

void foo() {
	cout << "foo\n";
}

void bar(int x) {
	cout << "bar\n";
}

int main() {
	//std::thread t1(myfunc_work);
	//cout << "main thread ....." << endl;
	 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑
	//t1.join();

	thread t1(foo);
	thread t2(bar, 10);
	cout << "main,foo,bar execute concurrently....\n";

	cout << "sleep 1s\n";
	this_thread::sleep_for(chrono::seconds(2));

	cout << "join t1\n";
	t1.join();
	cout << "join t2\n";
	t2.join();

	cout << "foo and bar thread complete";

}

很显然:新线程建立后,是否立即执行新线程业务代码,有一定的随机性。

但是我们可以通过 thread.join()  或者 sleep_for() 来控制代码执行顺序

3:建立新 thread执行类别中的函数

C++ std::thread 的构建可以传入class类别中的成员函数,如下范例所示:AA::start 分别建立t1, t2 两个线程,而 t1传入 AA::a1 类别函数。

notice :

第一个参数:AA::a1 前面需要添加 &

第二个参数:代表的是那个类对象

后面参数: 按照要求传入即可

class AA
{
public:
	void a1()
	{
		cout << "a1\n";
	}

	void a2(int n) {
		cout << "a2 : " << n << "\n";
	}

	void start() {
		thread t1(&AA::a1, this);
		thread t2(&AA::a2, this,10);

		t1.join();
		t2.join();
	}

private:

};

4:建立新 thread 执行 lambda expression

std:: thread 的构建也可以传入 lambda expression 表达式,如下范例:

5:join等待thread执行结束

在main主线程建立 t1线程后,主线程便继续往下执行,如果主线程需要等待 t1执行完毕后才能继续执行的话,就需要使用 join 。

等待 t1线程执行完 foo 后主线程才能继续执行,如果 t1线程没有执行完,主线程会一致阻塞在 join这一行。

void test2() {
	cout << "foo begin...." << endl;
	this_thread::sleep_for(chrono::milliseconds(5000));
	cout << "foo end...." << endl;
}

int main() {
	std::thread t1(test2);
	cout << "main 1....." << endl;;
	t1.join();
	cout << "main 2.....";

	cout << "main thread run over" << endl;
}

6:detach不等待 thread执行结束

承上例:如果主线程不想等或者可以不用等待 t1线程,可以使用 detach来让 t1线程分离,接着主线程就可以继续执行,t1线程 也在继续执行。

/**
	join等待thread执行结束
*/
void test2() {
	cout << "foo begin...." << endl;
	this_thread::sleep_for(chrono::milliseconds(50));
	cout << "foo end...." << endl;
}

int main() {

	std::thread t1(test2);
	cout << "main 1....." << endl;;
	t1.detach();
	cout << "main 2....."<< endl;

	cout << "main thread run over" << endl;
	Sleep(2000);
	return 0;
}

7:std::thread 参数传递使用引用的方法

定义方法:

void  myFunc(int&  n) {
        std::cout << "myFunc  n = " << n << endl;

        n+= 10;

}

使用参数传递使用引用目的是: 希望建立另外一个线程去执行 myFunc , 之后需要取得这个 myFunc的运算结果,但是建立线程如果写: std::thread t1(myFunc , n)  这样会编译出错。

因为在 std::thread 的参数传递方式为值传递,值传递是不可修改的左值,如果要让其能修改,可以考虑通过 : std::ref 来达成。

void myFunc(int n) {
	std::cout << "myFunc n = " << n << endl;
	n += 10;
}

void myFunc_ref(int& n) {
	std::cout << "myFunc reference n = " << n << endl;
	n += 10;
}

int main() {

	int n1 = 5;
	thread t1(myFunc, n1);
	t1.join();
	cout << "main n1 = " << n1 << "\n";

	int n2 = 10;
	thread t2(myFunc_ref, std::ref(n2));
	t2.join();
	cout << "main n2 = " << n2 << "\n";

	cout << "main thread run over" << endl;
	return 0;
}

到此这篇关于C++中std::thread线程用法的文章就介绍到这了,更多相关C++ std::thread线程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++11 并发指南之std::thread 详解

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用法. std::thread 在 <thread> 头文件中声明,因此使用 std::thread 时需要包含 <thread> 头文件. std::thread 构造 default (1) thread() noexcept; initialization (2) template

  • c++11中关于std::thread的join的详解

    std::thread是c++11新引入的线程标准库,通过其可以方便的编写与平台无关的多线程程序,虽然对比针对平台来定制化多线程库会使性能达到最大,但是会丧失了可移植性,这样对比其他的高级语言,可谓是一个不足.终于在c++11承认多线程的标准,可谓可喜可贺!!! 在使用std::thread的时候,对创建的线程有两种操作:等待/分离,也就是join/detach操作.join()操作是在std::thread t(func)后"某个"合适的地方调用,其作用是回收对应创建的线程的资源,避

  • C++ std::thread 使用方法

    目录 一.std::thread的构造和析构 二.std::thread的成员函数 三.线程间的通信 四.线程的异常处理 五.总结 总结: C++是一种高级编程语言,被广泛用于开发高性能.大规模.复杂的软件系统.其中一个强大的特性就是多线程编程,而std::thread是C++标准库提供的多线程支持的重要组成部分. std::thread是一个轻量级线程类,它允许程序员创建.启动.停止.等待线程.与其他多线程库不同,std::thread在运行时不需要显式地创建和销毁线程,而是通过构造和析构线程

  • C++11并发编程:多线程std::thread

    一:概述 C++11引入了thread类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的API,无法解决跨平台问题,一套代码平台移植,对应多线程代码也必须要修改.现在在C++11中只需使用语言层面的thread可以解决这个问题. 所需头文件<thread> 二:构造函数 1.默认构造函数 thread() noexcept 一个空的std::thread执行对象 2.初始化构造函数 template<class Fn, class... Args> explicit th

  • C++11中std::thread线程实现暂停(挂起)功能

    目录 一.封装Thread类 二.测试代码 一.封装Thread类 我们基于C++11中与平台无关的线程类std::thread,封装Thread类,并提供start().stop().pause().resume()线程控制方法. 为了让线程在暂停期间,处于休眠,不消耗CPU,我们使用C++11提供的锁和条件变量来实现. std::mutex std::condition_variable Thread.h #ifndef THREAD_H #define THREAD_H #include

  • C#中AutoResetEvent控制线程用法小结

    目录 AutoResetEvent主要方法及实践 第二种方法Semaphore 第三种方法,约定每个线程只干自己的事 第四种方法 Mutex 本文主要来自一道面试题,由于之前对AutoResetEvent的概念比较模糊(即使已经使用过了).面试题题目很简洁:两个线程交替打印0~100的奇偶数.你可以先动手试试,我主要是尝试在一个方法里面完成这个任务. 注: Suspend,Resume来控制线程已经在.net framework2.0被淘汰了,原因就是挂起之后,但因为异常而没有及时恢复,如果占用

  • C++语言中std::array的用法小结(神器用法)

    摘要:在这篇文章里,将从各个角度介绍下std::array的用法,希望能带来一些启发. td::array是在C++11标准中增加的STL容器,它的设计目的是提供与原生数组类似的功能与性能.也正因此,使得std::array有很多与其他容器不同的特殊之处,比如:std::array的元素是直接存放在实例内部,而不是在堆上分配空间:std::array的大小必须在编译期确定:std::array的构造函数.析构函数和赋值操作符都是编译器隐式声明的--这让很多用惯了std::vector这类容器的程

  • Java中线程用法总结

    本文实例总结了Java中线程用法.分享给大家供大家参考.具体分析如下: 1.线程是基本调度单元.共享进程的资源,如内存和文件句柄.但有自己的pc(程序计数器),stack(线程栈)及本地变量 2.线程的优势: a) 充分利用多处理器 b) 可以简化模型.特定任务给特定线程.如servlets及rmi等框架. c) 对异步事件的简单处理.如socket,nio使用更复杂.而现在的操作系统支持更大数量的线程. d) 界面的更佳响应 3.内部锁:synchronized块.互斥.可重入(reentra

  • 对python 多线程中的守护线程与join的用法详解

    多线程:在同一个时间做多件事 守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为thread.setDaemon(True),要在thread.start()之前设置,默认是false的,也就是主线程结束时,子线程依然在执行. thread.join():在子线程完成运行之前,该子线程的父线程(一般就是主线程)将一直存在,也就是被阻塞 实例: #!/usr/bin/python # encoding: utf-8 import threading fro

  • C++11中std::function与std::bind的用法实例

    目录 关于std::function 的用法: 关于std::bind 的用法: 附:std::function与std::bind双剑合璧 总结 关于std::function 的用法: 其实就可以理解成函数指针 1. 保存自由函数 void printA(int a) { cout<<a<<endl; } std::function<void(int a)> func; func = printA; func(2); 保存lambda表达式 std::functio

  • C++ boost thread库用法详细讲解

    目录 一.说明 二.boost::thread的几个函数 三.构造 一.说明 boost::thread的六种使用方法总结,本文初步介绍线程的函数.构造.执行的详细解释. 二.boost::thread的几个函数 函数 功能 join() 让主进程等待子线程执行完毕后再继续执行 get_id() 获得线程的 id 号 detach() 标线程就成为了守护线程,驻留后台运行 bool joinable() 是否已经启动,为 join() thread::join()是个简单暴力的方法,主线程等待子

  • JAVA 中Spring的@Async用法总结

    JAVA 中Spring的@Async用法总结 引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后,就已经内置了@Async来完美解决这个问题,本文将完成介绍@Async的用法. 1.  何为异步调用? 在解释异步调用之前,我们先来看同步调用的定义:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果. 异步调用则是只是发送了调用的

  • Python守护线程用法实例

    本文实例讲述了Python守护线程用法.分享给大家供大家参考,具体如下: 如果你设置一个线程为守护线程,就表示你在说这个线程是不重要的,在进程退出的时候,不用等待这个线程退出.如果你的主线程在退出的时候,不用等待那些子线程完成,那就设置这些线程的daemon属性.即在线程开始(thread.start())之前,调用setDeamon()函数,设定线程的daemon标志.(thread.setDaemon(True))就表示这个线程"不重要". 如果你想等待子线程完成再退出,那就什么都

随机推荐