让我来详细讲解C++11获取线程返回值的实现代码,包括以下几个步骤:
第一步:定义线程函数
在使用C++11获取线程返回值时,我们需要先定义一个线程函数,该函数负责执行耗时的代码逻辑,并返回需要的结果。例如,下面这个线程函数将通过计算两个整数的和来返回一个结果:
int sum(int a, int b) {
return a + b;
}
第二步:创建线程实例
接下来,我们需要创建一个线程实例,该实例将运行我们定义的线程函数。在创建线程实例时,我们需要把线程函数的指针作为参数传入,如下:
std::thread t(sum, 1, 2);
上述代码中,我们创建了一个名称为t
的线程实例,该实例将以sum
函数为入口,同时传入参数1
和2
,即执行sum(1, 2)
。
第三步:等待线程执行完成并获取结果
线程实例创建完成后,我们需要等待线程执行完成,并获取线程返回的结果。C++11提供了join()
方法和detach()
方法,可以分别用于等待线程执行完成和分离线程。
在获取线程返回值的场景下,我们通常使用join()
方法等待线程执行完成,并通过C++11提供的std::packaged_task
和std::future
来获取线程返回值。std::packaged_task
表示一个可调用对象的封装,包含了一个函数对象,并可以运行该函数;std::future
表示一个异步操作的结果,可以用来获取该异步操作的返回值。
通过将线程函数包装成一个std::packaged_task
,我们可以异步运行该函数,并使用std::future
来获取其返回值。具体代码如下:
std::packaged_task<int(int, int)> task(sum);
std::future<int> result = task.get_future();
std::thread t(std::move(task), 1, 2);
t.join();
int res = result.get();
std::cout << "sum result: " << res << std::endl;
上述代码中,我们首先创建了一个std::packaged_task
实例task
,将sum
函数作为参数传入。然后通过task.get_future()
方法获取一个std::future
实例result
,该实例用于存储线程函数的返回值。接着,我们使用std::thread
创建一个线程实例t
,并将task
移动到线程实例中运行。
在线程实例执行完成后,我们通过result.get()
方法等待线程执行完成并获取结果,将结果存储在变量res
中。最后,我们通过输出语句将结果输出到控制台。
示例说明一
我们假设有一个需求:在主线程中计算10个数字的平均数,可以使用10个子线程并发地计算每个数字,最终统计整体平均数。具体实现代码如下:
#include <iostream>
#include <thread>
#include <vector>
#include <future>
double CalcAvg(std::vector<int>& nums) {
size_t len = nums.size();
std::vector<std::future<double>> results;
for (size_t i = 0; i < len; ++i) {
std::packaged_task<double()> task([&nums, i]() {
return nums[i];
});
results.emplace_back(task.get_future());
std::thread(std::move(task)).detach();
}
double total = 0.0;
for (size_t i = 0; i < len; ++i) {
total += results[i].get();
}
return total / len;
}
int main() {
std::vector<int> nums{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::cout << "Avg: " << CalcAvg(nums) << std::endl;
return 0;
}
上述代码中,我们首先定义了一个CalcAvg
函数,该函数接收一个std::vector<int>
类型的数字数组作为参数,并返回该数组的平均数。
在CalcAvg
函数中,我们首先使用results
数组存储每个子线程返回的结果。接着,我们遍历数字数组,通过std::packaged_task
和std::future
将每个数字的计算封装为一个异步任务,并将任务的返回值存储到results
数组中。
在所有子线程执行完成后,我们遍历results
数组,将所有子线程返回的结果相加,得到总和total
。最后,我们返回total
除以数字数组长度的平均数。
示例说明二
我们假设有一个需求:在主线程中启动10个子线程,每个子线程随机生成一个整数,并打印该整数值。具体代码实现如下:
#include <iostream>
#include <thread>
#include <random>
void PrintRandomNum() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 100);
int num = dis(gen);
std::cout << "thread id: " << std::this_thread::get_id() << ", random number: " << num << std::endl;
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back(PrintRandomNum);
}
for (auto& t : threads) {
t.join();
}
return 0;
}
上述代码中,我们首先定义了一个PrintRandomNum
函数,该函数使用C++11提供的std::random_device
、std::mt19937
、std::uniform_int_distribution
等类生成随机整数,并输出该整数值和线程ID。
在main
函数中,我们首先创建一个threads
数组,用于存储10个子线程实例。然后,通过循环10次,创建10个线程实例并使用threads.emplace_back
方法将每个线程实例放入threads
数组中。接着,我们使用for
循环遍历threads
数组,并使用join
方法等待所有子线程执行完成。
在输出结果中,我们可以看到每个子线程都可以独立响应并输出结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11获取线程返回值的实现代码 - Python技术站