网站首页 > 基础教程 正文
在现代软件开发中,异步编程已成为提升程序性能和响应能力的关键技术之一。C++,作为一种性能优异的编程语言,其异步编程的实现方式也随着语言标准的演进而不断进化。本文将从C++的早期版本到最新的C++20标准,深入探讨异步编程的演进过程,并提供丰富的代码示例。
早期的多线程编程
在C++11之前,多线程编程主要依赖于平台特定的库,如POSIX线程库(pthread)。这种方式虽然可行,但使用起来相当繁琐。
pthread的使用示例
以下是一个使用pthread库实现的简单线程计算示例:
#include <pthread.h>
#include <iostream>
#include <unistd.h>
struct Data {
int a;
int b;
};
void* compute(void* arg) {
Data* data = static_cast<Data*>(arg);
int* sum = new int;
if (nullptr == sum) {
std::cerr << "Failed to create buffer for task." << std::endl;
return nullptr;
}
*sum = data->a + data->b;
sleep(2); // Simulate a time-consuming task
return sum;
}
int main() {
pthread_t thread;
Data data = {3, 4};
void* ret_val = nullptr;
if (pthread_create(&thread, nullptr, compute, &data) != 0) {
std::cerr << "Failed to create thread!" << std::endl;
return -1;
}
if (pthread_join(thread, &ret_val) != 0) {
std::cerr << "Failed to get compute result!" << std::endl;
return -2;
} else {
if (nullptr == ret_val) {
std::cerr << "Failed to get compute result!" << std::endl;
return -3;
} else {
std::cout << "Computed result: " << *static_cast<int*>(ret_val) << std::endl;
}
}
return 0;
}
这段代码展示了如何创建一个线程,执行一个简单的加法计算,并等待线程完成以获取结果。
C++11的std::thread
C++11引入了std::thread,极大地简化了线程的创建和管理。std::thread是一个类模板,可以直接创建线程对象。
使用std::thread的示例
以下是使用std::thread重写上述示例:
#include <thread>
#include <chrono>
#include <iostream>
void compute(int a, int b, int** res) {
int* sum = new int;
*sum = a + b;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Simulate a time-consuming task
if (nullptr == res) {
std::cerr << "Cannot transfer result." << std::endl;
} else {
*res = sum;
}
}
int main() {
int* ret_val = nullptr;
std::thread t(compute, 3, 4, &ret_val);
t.join();
if (ret_val != nullptr) {
std::cout << "Computed result: " << *ret_val << std::endl;
delete ret_val;
ret_val = nullptr;
}
return 0;
}
在这个示例中,我们使用std::thread创建了一个线程,并传递了计算参数和结果存储地址。这种方式比使用pthread更简洁。
std::promise和std::future
为了更好地处理线程间的数据传递,C++11还引入了std::promise和std::future。这两个类配合使用,可以简化线程间的数据共享。
使用std::promise和std::future的示例
以下是使用std::promise和std::future重写的计算示例:
#include <thread>
#include <future>
#include <utility>
#include <chrono>
#include <iostream>
void compute(int a, int b, std::promise<int>&& promise) {
int sum = a + b;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Simulate a time-consuming task
promise.set_value(sum);
}
int main() {
std::promise<int> promise;
std::future<int> future = promise.get_future();
std::thread t(compute, 3, 4, std::move(promise));
std::cout << "Computed result: " << future.get() << std::endl;
t.join();
return 0;
}
在这个示例中,我们使用std::promise来传递计算结果,并通过std::future在主线程中获取结果。
std::packaged_task
std::packaged_task是另一个有用的工具,它封装了任务函数和std::promise,使得线程函数的返回值可以直接传递给std::future。
使用std::packaged_task的示例
以下是使用std::packaged_task重写的计算示例:
#include <future>
#include <iostream>
int compute(int a, int b) {
return a + b;
}
int main() {
std::packaged_task<int(int, int)> task(compute);
std::future<int> result = task.get_future();
std::thread t(std::move(task), 3, 4);
t.detach();
std::cout << "Computed result: " << result.get() << std::endl;
return 0;
}
在这个示例中,我们使用std::packaged_task来封装计算函数,并通过std::future获取结果。
std::async
std::async是一个高级工具,它封装了std::packaged_task和std::thread,允许你以非常简洁的方式启动异步任务。
使用std::async的示例
以下是使用std::async的示例:
#include <future>
#include <iostream>
int compute(int a, int b) {
return a + b;
}
int main() {
std::future<int> result = std::async(std::launch::async, compute, 3, 4);
std::cout << "Computed result: " << result.get() << std::endl;
return 0;
}
在这个示例中,我们使用std::async启动了一个异步任务,并在主线程中获取结果。
C++20的新特性
C++20引入了std::jthread和协程,进一步简化了异步编程。
std::jthread的示例
以下是使用std::jthread的示例:
#include <jthread>
#include <iostream>
void compute(int a, int b) {
std::this_thread::sleep_for(std::chrono::seconds(1)); // Simulate a time-consuming task
std::cout << "Computed result: " << a + b << std::endl;
}
int main() {
std::jthread t(compute, 3, 4);
return 0;
}
在这个示例中,我们使用std::jthread来启动一个异步任务,它会自动管理线程的生命周期。
协程的示例
以下是使用协程的示例:
#include <iostream>
#include <coroutine>
#include <thread>
generator<int> compute(int a, int b) {
std::this_thread::sleep_for(std::chrono::seconds(1)); // Simulate a time-consuming task
yield a + b;
}
int main() {
for (auto result : compute(3, 4)) {
std::cout << "Computed result: " << result << std::endl;
}
return 0;
}
在这个示例中,我们使用协程来执行异步任务,并在主线程中获取结果。
结论
C++的异步编程随着语言标准的演进而不断进化,从早期的pthread到现代的std::async和协程,C++提供了丰富的工具来简化异步编程。这些工具不仅提高了程序的性能,也提高了代码的可读性和可维护性。
猜你喜欢
- 2024-11-11 Linux下的C++ socket编程实例 linux c++ tcp
- 2024-11-11 C++11原子变量:线程安全、无锁操作的实例解析
- 2024-11-11 C++11的thread_local原理和应用范例
- 2024-11-11 知识重构-c++ : Lambda 知识重构拼音
- 2024-11-11 c++ 疑难杂症(4) std:vector c++ vector subscript out of range
- 2024-11-11 C++ 开发中使用协程需要注意的问题
- 2024-11-11 golang极速嵌入式Linux应用开发(四)-协程与并发
- 2024-11-11 在计算机编程中,线程是指一个程序内部的执行流程
- 2024-11-11 C++ std:decay、std:bind、std:packaged_task 在模版编程的实践
- 2024-11-11 Linux/C++简单线程池实现 了解Java语言对于多线程的支持多丰富
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)