当前位置: 首页 > wzjs >正文

昆明模板建站定制网站百度seo关键词排名s

昆明模板建站定制网站,百度seo关键词排名s,长春建站推荐,自动化培训机构排名std::promise 是 C11 引入的一个类,用于在线程之间传递异步结果(值或异常)。它通常与 std::future 配合使用,std::promise 用于设置值或异常,而 std::future 用于获取这些值或异常。 下面通过一个更直观的生产者-消费者…

std::promise 是 C++11 引入的一个类,用于在线程之间传递异步结果(值或异常)。它通常与 std::future 配合使用,std::promise 用于设置值或异常,而 std::future 用于获取这些值或异常。


下面通过一个更直观的生产者-消费者场景,展示 std::promise 如何在线程间传递结果:


示例:生产者线程计算平方,消费者线程获取结果

#include <iostream>
#include <thread>
#include <future>
#include <chrono>// 生产者线程:计算某个数的平方,并将结果通过 promise 传递
void producer_task(std::promise<int> result_promise, int input) {// 模拟耗时计算std::this_thread::sleep_for(std::chrono::seconds(1));// 计算平方int square = input * input;// 将结果设置到 promise 中(传递到消费者线程)result_promise.set_value(square);
}// 消费者线程:等待结果并处理
void consumer_task(std::future<int> result_future) {// 阻塞等待结果(从生产者线程获取)int result = result_future.get();// 处理结果std::cout << "消费者线程收到结果: " << result << std::endl;
}int main() {// 1. 创建 promise 和 futurestd::promise<int> prom;std::future<int> fut = prom.get_future();// 2. 启动生产者线程(计算 5 的平方)std::thread producer(producer_task, std::move(prom), 5);// 3. 启动消费者线程(处理结果)std::thread consumer(consumer_task, std::move(fut));// 等待线程结束producer.join();consumer.join();return 0;
}

代码解释

1. 生产者线程 (producer_task)
  • 输入:接收一个 std::promise<int> 和一个整数 input
  • 操作
    • 模拟耗时计算(1秒)。
    • 计算 input 的平方。
    • 将结果通过 promise.set_value() 设置到 promise 中。
  • 作用:将计算结果传递给其他线程。
2. 消费者线程 (consumer_task)
  • 输入:接收一个 std::future<int>
  • 操作
    • 调用 future.get() 阻塞等待结果。
    • 获取结果后打印。
  • 作用:从其他线程获取结果并进行处理。
3. 主线程
  • 创建 std::promise<int> 和关联的 std::future<int>
  • promise 传递给生产者线程,将 future 传递给消费者线程。
  • 等待两个线程完成。

关键点

  1. 线程间结果传递

    • 生产者线程通过 promise.set_value() 设置结果。
    • 消费者线程通过 future.get() 获取结果。
  2. 所有权转移

    • std::promisestd::future 不可复制,但可通过 std::move 转移所有权。
    • 主线程将 promise 移入生产者线程,future 移入消费者线程。
  3. 同步机制

    • future.get() 会阻塞消费者线程,直到生产者线程调用 promise.set_value()

输出结果

程序运行后输出:

消费者线程收到结果: 25

更贴近实际的应用场景

假设生产者线程需要从网络下载数据,消费者线程需要处理数据:

void downloader(std::promise<std::string> data_promise) {// 模拟下载数据std::this_thread::sleep_for(std::chrono::seconds(2));data_promise.set_value("下载完成的数据");
}void data_processor(std::future<std::string> data_future) {std::string data = data_future.get();std::cout << "处理数据: " << data << std::endl;
}int main() {std::promise<std::string> prom;std::future<std::string> fut = prom.get_future();std::thread t1(downloader, std::move(prom));std::thread t2(data_processor, std::move(fut));t1.join();t2.join();return 0;
}

总结

  • std::promise 的作用:作为生产者线程的结果出口。
  • std::future 的作用:作为消费者线程的结果入口。
  • 适用场景:需要明确分离“结果生产者”和“结果消费者”的多线程任务。

那么,如果不使用std::promise的话,两个线程间如何传递数据呢?


在 C++ 中,如果不使用 std::promisestd::future,线程间传递数据可以通过其他同步机制实现。以下是几种常见方法:


1. 共享数据 + 互斥锁 (std::mutex)

通过共享变量传递数据,使用 std::mutex 保护共享数据,防止数据竞争。

示例:
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>std::mutex mtx;
int shared_data = 0;void producer() {std::this_thread::sleep_for(std::chrono::seconds(1));std::lock_guard<std::mutex> lock(mtx);shared_data = 42; // 生产者写入数据
}void consumer() {std::lock_guard<std::mutex> lock(mtx);std::cout << "消费者收到数据: " << shared_data << std::endl;
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

缺点:需要手动同步,容易因锁的顺序不当导致死锁。


2. 条件变量 (std::condition_variable)

通过条件变量通知其他线程数据已就绪,通常与互斥锁和共享变量配合使用。

示例:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool data_ready = false;
int shared_data = 0;void producer() {std::this_thread::sleep_for(std::chrono::seconds(1));{std::lock_guard<std::mutex> lock(mtx);shared_data = 42;data_ready = true;}cv.notify_one(); // 通知消费者
}void consumer() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return data_ready; }); // 等待数据就绪std::cout << "消费者收到数据: " << shared_data << std::endl;
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

优点:避免忙等待,效率更高。


3. 原子操作 (std::atomic)

对简单数据类型(如 intbool)使用原子变量,无需显式加锁。

示例:
#include <iostream>
#include <thread>
#include <atomic>std::atomic<int> atomic_data(0);void producer() {std::this_thread::sleep_for(std::chrono::seconds(1));atomic_data.store(42); // 原子写入
}void consumer() {while (atomic_data.load() == 0) { // 原子读取std::this_thread::yield(); // 避免忙等待}std::cout << "消费者收到数据: " << atomic_data.load() << std::endl;
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

缺点:仅适用于基本数据类型,无法处理复杂对象。


4. 消息队列(生产者-消费者模式)

使用队列作为缓冲区,生产者写入数据,消费者读取数据。需配合互斥锁和条件变量。

示例:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::mutex mtx;
std::condition_variable cv;
std::queue<int> msg_queue;void producer() {for (int i = 0; i < 5; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(500));{std::lock_guard<std::mutex> lock(mtx);msg_queue.push(i);}cv.notify_one(); // 通知消费者}
}void consumer() {while (true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return !msg_queue.empty(); });int data = msg_queue.front();msg_queue.pop();std::cout << "消费者收到数据: " << data << std::endl;if (data == 4) break; // 结束条件}
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

优点:适合处理大量数据或流式数据。


5. 回调函数(函数参数传递)

通过函数参数直接将数据传递给线程,但需注意线程的生命周期。

示例:
#include <iostream>
#include <thread>
#include <chrono>void consumer(int data) {std::cout << "消费者收到数据: " << data << std::endl;
}int main() {int data = 42;std::thread t(consumer, data); // 通过参数传递数据t.join();return 0;
}

缺点:仅适用于一次性数据传递,无法异步修改。


6. 全局变量

直接通过全局变量传递数据(需谨慎,通常不推荐)。

示例:
#include <iostream>
#include <thread>
#include <chrono>int global_data = 0;void producer() {std::this_thread::sleep_for(std::chrono::seconds(1));global_data = 42;
}void consumer() {while (global_data == 0) {std::this_thread::yield();}std::cout << "消费者收到数据: " << global_data << std::endl;
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

缺点:不安全,易引发数据竞争。


总结

方法适用场景优点缺点
共享数据 + 互斥锁简单数据,少量访问灵活通用需手动管理锁,易死锁
条件变量需要等待特定条件高效,避免忙等待代码复杂度较高
原子操作基本数据类型,无锁需求无锁,高效仅支持基本类型
消息队列大量数据或流式处理扩展性强实现复杂
回调函数一次性数据传递简单直接无法动态更新数据
全局变量快速原型开发(不推荐生产环境)简单不安全,易引发数据竞争

根据具体需求选择合适的方法。对于异步结果传递,std::promisestd::future 是最安全和简洁的方案,但在其他场景下,上述方法可能更灵活。

http://www.dtcms.com/wzjs/267142.html

相关文章:

  • 物流企业网站建设个人做seo怎么赚钱
  • 一家专做节日商品的网站百度sem竞价推广pdf
  • 文本怎样做阅读链接网站中国推广网
  • 有什么网上做c 的网站淘宝大数据查询平台
  • 重庆企业网站定制媒体代发布
  • wordpress批量导入全面的seo网站优化排名
  • 网站添加地图导航企业网站定制开发
  • 做公司网站 找谁做seo去哪里培训
  • 京津冀协同发展规划纲要关键词优化步骤简短
  • 哪里有做效果图的网站西安网站关键词优化费用
  • 网站空间地址郑州网站优化外包
  • 网站的总体风格包括百度浏览器
  • seo网站推广实例网站设计与实现毕业设计
  • 深圳设计研究院总院优化王
  • 商城网站开发那家好网站建设找哪家公司好
  • 2016网站设计规范推广策划方案
  • 广州网站建设中心国内免费二级域名建站
  • 石家庄招标信息网济南优化seo公司
  • 个人网页模板网站武汉seo报价
  • 外贸网站做推广seo关键词优化软件手机
  • 北京招聘网站设计师百度seoo优化软件
  • 廊坊seo淄博seo网站推广
  • 聊城高端网站制作百度视频免费下载
  • 免费广告语设计生成器百度seo入驻
  • wordpress集成当面付郑州seo代理外包公司
  • 网站主机做外挂抖音seo排名软件
  • 最好的网站建设免费的网络营销概述ppt
  • wordpress做视频播放网站网络市场调研的方法
  • 抚州网站seo最快新闻资讯在哪看
  • 北京师范大学学风建设专题网站aso优化前景