std future get_waitkey(0)

std future get_waitkey(0)一、关于std::future成员函数wait_for():1.1关于std::future_status:std::future_status是一个枚举类型,其值有三://ENUMfuture_statusenumclassfuture_status{//namesfortimedwaitfunctionreturnsready,timeout,deferred//延迟执行,当std::async()第一个参数为std::lanuch::de

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、关于std::future成员函数wait_for()

1.1 关于std::future_status
std::future_status是一个枚举类型,其值有三:

// ENUM future_status
enum class future_status { 
    // names for timed wait function returns
    ready,
    timeout,
    deferred//延迟执行,当std::async()第一个参数为std::lanuch::deferred时生效。
};

1.2 wait_for():
返回值类型为future_status,该函数将本线程阻塞在当前,并等待一段时间,后继续执行,若在等待时间内wait_for()绑定线程执行完毕,则返回ready,未执行完毕则返回timeout

int myThread1(int arg)
{ 
   
	cout << arg << endl;
	cout << "myThread() START..." << " thread_id:" << std::this_thread::get_id() << endl;
	Sleep(5000);
	cout << "myThread() END..." << " thread_id:" << std::this_thread::get_id() << endl;
	return 5;
}

int main()
{ 
   
	cout << "main thread id:" << std::this_thread::get_id() << endl;
	std::future<int>result = std::async(myThread1, 3);
	cout << "continue..." << endl;

	//枚举类型
	std::future_status status = result.wait_for(std::chrono::seconds(3));//设置等待3s,根据设置等待时间与子线程执行消耗时间得到返回值。决定程序在当前行阻塞时间。
	if (status == std::future_status::timeout)//子线程还没执行完
	{ 
   
		cout << "timeout..." << endl;
		//cout << result.get() <<endl;
	}
	else if (status == std::future_status::ready)//子线程已执行完
	{ 
   
		cout << "ready..." << endl;
		//cout << result.get() << endl;
	}
	
	return 0;
}

关于枚举类型值deferred:

std::future<int>result = std::async(std::launch::deferred,myThread1, 3);

当std::async()第一个参数为std::lanuch::deferred时生效。此时线程不在阻塞在wait_for()处,而是继续执行直到遇见属于该future对象的get()

	else if (status==std::future_status::deferred)
	{ 
   
		cout << "deferred act" << endl;
		cout << result.get();
	}

注意:无论std::async()是否延迟执行,异步线程都将会指向完程序才能结束,三种结束方式:

  • 阻塞在wait_for()处等待异步线程结束
  • 阻塞在get()处等待异步线程结束
  • 阻塞在return 0;处等待异步线程结束

get()函数只能使用一次,因为get()函数的设计是一个移动语义,相当于将future对象中的值转移到了get()调用者中,所以再次get()就报告了异常。

二、std::shared_future

也是类模板,其get()函数复制数据。

在实际开发中,有时候某线程的值不止被一个线程所需要,而get()却只能只用一次,这时可以通过std::shared_future达到多次通过get()获取值的目的:

	std::future<int>myf = mypt.get_future();
	std::shared_future<int>myf_s(myf.share());

	std::thread t2(mythread1,std::ref(myf_s));
	t2.join();

	auto mysf = myf_s.get();
	cout << mysf << " -" << endl;

	cout << "---------------" << endl;

	auto mysf2 = myf_s.get();
	cout << mysf2 << " -" << endl;

如上,用std::future初始化std::shared_future对象,通过std::shared_future即可多次调用get()获取线程返回。

也可不通过std::future连接std::shared_futurepackaged_task对象:

//原:
	std::future<int>myf = mypt.get_future();
	std::shared_future<int>myf_s(myf.share());
//简化:
	std::shared_future<int>myf_s = mypt.get_future();

三、原子操作std::atomic
std::atomic来代表原子操作,是个类模板。其实std::atomic是用来封装某个类型的值的

原子操作: 在多线程中不会被打断的程序执行片段。

效率上: 原子操作要比互斥量的方式效率要高。

  • 互斥量的加锁一般是针对一个代码段,而原子操作针对的一般都是一个变量。

  • 原子操作,一般都是指* 不可分割的操作 * ;也就是说这种操作状态要么是完成的,要么是没完成的,不可能出现半完成状态。

注意使用时需要添加#include <atomic>头文件

实例1:计算自增后的值:

std::atomic<int> g_count = 0;

void myThread()
{ 
   
	for (size_t i = 0; i < 10000000; i++)
		g_count++;
}

int main()
{ 
   
	std::thread t1(myThread);
	std::thread t2(myThread);
	t1.join();
	t2.join();

	cout << g_count << endl;
	return 0;
}

实例2:判断线程是否结束

std::atomic<bool> g_ifend = false;

void myThread()
{ 
   
	std::chrono::milliseconds dura(1000);
	while (g_ifend==false)
	{ 
   
		cout << "thread is working" << "--- " << std::this_thread::get_id() << endl;
		std::this_thread::sleep_for(dura);
		//Sleep(1);
	}
	cout << "----- end -----" << "--- " << std::this_thread::get_id() << endl;
}

int main()
{ 
   
	std::thread t1(myThread);
	std::thread t2(myThread);
	//Sleep(5);
	std::chrono::milliseconds dura1(5000);
	std::this_thread::sleep_for(dura1);
	g_ifend = true;
	t1.join();
	t2.join();

	return 0;
}

原子操作一般用于计数或者统计(如数据包的累计发送或者接受数目),如果多个线程一起统计,不使用原子操作会导致统计发生混乱。

更多内容欢迎参见我的个人网站:http://www.huazhige.online/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196376.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【面试真经】2020年7月 Linux运维面试题(含答案版)

    【面试真经】2020年7月 Linux运维面试题(含答案版)一.在当前文件目录下,有文件file1查询file1里面空行的所在行号查询file2以abc结尾的行打印出file1文件第一行到第3行二.如何将本地80端口的请求转发到8080端口,当前的主机IP为192.168.2.1三.crontab如何设置在11月份的每天早上6点到12点中,每隔2个小时执行/usr/bin/httpd.sh怎么实现四.编写个shell脚本将/usr/local/test目录下大于100K的文件转移到/tmp目录下五.简述raid0ra

    2022年6月10日
    33
  • 大数据_01【介绍】

    大数据_01【介绍】大数据_01【介绍】大数据特点大数据能做什么【海量数据背景下】大数据行业的应用大数据发展前景大数据部门组织结构什么是大数据 指数据集的大小超过了现有典型数据库软件和工具的处理能力的数据大数据特点海量化 数据量从TB到PB多样化 数据类型复杂,超过百分之八十是非结构化的[结构化数据半结构化数据完全非结构化数据]快速化 数据量在持续增加(两位数的增长率),数据处理速度要求高高价值 在海量多样数据的快速分析下能发挥出更高的数据价值大数据能

    2022年5月10日
    42
  • Java——JDBC连接数据库(步骤详解!!!)

    Java——JDBC连接数据库(步骤详解!!!)JDBC的全称是:JavaDatabaseConnectivity,即Java数据库连接。JDBC可以通过载入不同的数据库的“驱动程序”而与不同的数据库进行连接。那么,在数据库连接的时候,我使用的是MySQL,Java集成开发环境是Eclipse。要使用JDBC来访问MySQL数据库,首先需要添加MySQL数据库驱动程序。下面,我来为大家讲解一下这其中的步骤(听着名字很高大上,但仔细看步骤会觉得其实没那么难!!!)????????????Step1:www.mysql.co

    2022年7月26日
    14
  • 国外的大龄程序员在干什么工作_为什么程序员年龄大了没人要

    国外的大龄程序员在干什么工作_为什么程序员年龄大了没人要在Quora有个帖子:我今年35岁了,是不是太老了,没法加入Google,Facebook,Microsoft或者Apple了?下面的回复让人叹为观止,我摘录几个:萨特南·辛格Google软件工程师(2017–present)不,我在51岁的时候加入了Google,我们团队还有几个比我年长的人!他们都是非常卓越的软件工程师,一生都在编程,并且获得了被认为非…

    2025年11月8日
    2
  • C# 中 Struct 与 Class 的区别,以及两者的适用场合

    C# 中 Struct 与 Class 的区别,以及两者的适用场合

    2021年7月30日
    58
  • C语言和JAVA的区别[通俗易懂]

    C语言和JAVA的区别[通俗易懂]java语言和c语言的区别:un公司推出的Java是面向对象程序设计语言,其适用于Internet应用的开发,称为网络时代重要的语言之一。Java可以用认为是C的衍生语言,与C在大量元以内成分保持相同,例如此法结构、表达式语句、运算符等与C基本一致:但Java更简洁,没有C中冗余以及容易引起异常的功能成分,并且增加了多线程、异常处理、网络编程等方面的支持功能。本文从多角度对Java与C进行对比分析,为C与Java语言的学习提高一些借鉴。1、调法结构C与Java的词法结构很相似,针对程

    2022年7月7日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号