C++ 11 多线程之promise

什么是std::promise?

std::promise 对象可以保存某一类型 T 的值,该值能被 std::future 对象读取(存在是另一个线程的可能),所以std::promise 提供了一种线程同步的手段。std::promise像一个外卖盒子,不同的线程可以通过这个盒子传递数据。

std::promise的构成

在这里插入图片描述

  • 基础函数(构造、析构、赋值):
    默认构造函数会初始化一个空的共享状态;禁止拷贝构造,同时赋值操作被禁止,只提供了移动构造;另外支持带allocator的构造函数
    析构函数:如果有std::future对象关联到同一共享状态,共享状态本身不会被销毁。如果在共享状态就绪前被销毁,则会为共享状态自动准备一个std::future_error异常,并使其处于就绪状态

  • operator=函数:禁用拷贝赋值,但可以移动赋值。

  • swap函数:交换 promise 的共享状态。

  • get_future函数:返回一个与promise对象共享状态关联的std::future对象。当就绪时,std::future对象就可以访问promise对象在共享状态上设置的值或异常。每个promise共享状态仅能被一个std::future对象检索。若调用此函数后,promise应在某个时刻使其共享状态准备就绪(通过设置值或异常),否则一个std::future_error将在销毁时自动准备就绪。

  • set_value函数:即设置共享状态的值,共享状态的标志设置为ready。

  • set_value_at_thread_exit函数:设置共享状态的值,但并不将该共享状态的标志设置为ready,当线程退出时,该promise对象会自动设置为ready。

  • set_exception函数:设置共享状态的异常指针,共享状态的标志设置为ready。

  • set_exception_at_thread_exit函数:设置共享状态的异常指针,但并不将该共享状态的标志设置为ready,当线程退出时,该promise对象会自动设置为ready

代码释义

最简单的作为线程之间传递数据

#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

void GetCalcuSum(std::vector<int>::iterator begin, std::vector<int>::iterator end,
	std::promise<int> accumulate_promise)
{
	std::this_thread::sleep_for(std::chrono::milliseconds(500));
	int total = std::accumulate(begin, end, 0); //自动求和
	std::this_thread::sleep_for(std::chrono::milliseconds(500));
	accumulate_promise.set_value(total);        // 提醒 future
}


void SimpleThreadData() {
	// 演示用 promise<int> 在线程间传递结果。
	std::vector<int>  numbers = {1, 2, 3, 4, 5, 6};
	std::promise<int> total_promise;
	std::future<int>  accumulate_future = total_promise.get_future(); //绑定
	std::thread       work_thread(GetCalcuSum, numbers.begin(), numbers.end(), std::move(total_promise));
	//std::future::get() 将等待直至该std::promise共享状态就绪
	std::cout << "result=" << accumulate_future.get() << std::endl;
	work_thread.join(); // wait for thread completion
}

void SimpleThreadEnd()
{
	auto sum_fun_exit = [&](std::vector<int>::iterator begin, std::vector<int>::iterator end,
			   std::promise<int> &accumulate_promise) {
		std::cout << "set_value_at_thread_exit" << std::endl;
		//accumulate_promise.set_value_at_thread_exit(1000); // 提醒 future
		std::this_thread::sleep_for(std::chrono::milliseconds(3000));
		std::cout << "thread_exit" << std::endl;
	};
	auto sum_fun_value = [&](std::vector<int>::iterator begin, std::vector<int>::iterator end,
				std::promise<int>& accumulate_promise) {
		std::cout << "set_value" << std::endl;
		accumulate_promise.set_value(999); // 对比
		std::this_thread::sleep_for(std::chrono::milliseconds(3000));
		std::cout << "thread_exit" << std::endl;
	};
	std::vector<int>  numbers = {1, 2, 3, 4, 5, 6};
	std::promise<int> total_promise;
	std::future<int>  accumulate_future = total_promise.get_future(); //绑定
	std::thread       work_thread(sum_fun_exit, numbers.begin(), numbers.end(), std::ref(total_promise));
	std::cout << "result=" << accumulate_future.get() << std::endl;
	work_thread.join(); // wait for thread completion
}

void SimpleBindOnce()
{
	// 演示只能与一个future绑定。
	std::vector<int>  numbers = {1, 2, 3, 4, 5};
	std::promise<int> total_promise;
	std::future<int>  total_future1 = total_promise.get_future(); //绑定
	try {
		std::future<int> total_future2 = total_promise.get_future(); //绑定
	} catch (const std::future_error& e) {
		std::cout << "future_error : " << e.what() << std::endl;
	}
}


int main()
{
	SimpleThreadEnd();

	//SimpleThreadData();

	//SimpleBindOnce();
}

结果(对比 set_value_at_thread_exit)
在这里插入图片描述
在这里插入图片描述

<think>好的,用户需要我生成一个完整代码示例,但根据提供的引用内容,每个引用都提到无法提供完整代码,只能给出简化片段或框架。这可能是因为完整代码涉及多个层面,比如前端后端数据库等,而且篇幅有限。我需要先确认用户具体需要哪种编程语言或框架的示例,然后根据已有的引用提供相应的简化代码,并建议如何扩展。同时,要遵循系统级指令,正确使用LaTeX格式,生成相关问题,并在回答中自然添加引用标识。需要确保回答结构清晰,帮助用户逐步解决问题,并且真实可靠。首先,用户可能对某个具体的编程语言或项目类型感兴趣,比如Java、Python、JavaScript等,或者前端后端的不同部分。根据引用4中的例子,可以提供一个简单的Java程序。然后,根据引用1和2,可以给出前端后端简化代码示例。最后,生成相关问题,引导用户进一步探索。需要注意使用中文,避免使用Markdown,保持口语化,但不要出现格式问题。</think>由于完整代码的复杂性较高,不同编程语言和功能模块的实现方式差异较大,我将为您提供几个关键模块的简化示例及扩展思路,帮助您理解代码结构。 ### 一、前端界面示例(HTML/JavaScript) ```html <!-- 商品展示模块 --> <div id="product-list"> <div class="product"> <h3>$productName</h3> <p>价格:$price</p> <button onclick="addToCart('$productId')">加入购物车</button> </div> </div> <script> // 购物车操作逻辑 let cart = []; function addToCart(productId) { const product = products.find(p => p.id === productId); cart.push(product); updateCartCount(cart.length); } </script> ``` 注:此为响应式界面基础实现,需配合CSS样式和API调用[^1] ### 二、后端接口示例(Python/Flask) ```python from flask import Flask, jsonify app = Flask(__name__) @app.route('/api/products') def get_products(): products = [ {"id": 1, "name": "商品A", "price": 99}, {"id": 2, "name": "商品B", "price": 199} ] return jsonify(products) if __name__ == '__main__': app.run(debug=True) ``` 注:RESTful API基础实现,需增加数据库连接和身份验证[^2] ### 三、数据库模型示例(SQL) ```sql CREATE TABLE Users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password_hash CHAR(60) NOT NULL ); CREATE TABLE Products ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) NOT NULL, price DECIMAL(10,2) CHECK (price > 0) ); ``` 注:关系型数据库基础表结构,需增加索引和关联表[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值