详情:
在下面的程序中,多个threads
(本例中为简单起见只有2个)监听从函数返回的相同的值66,遵循两个函数中产生结果66
的一些逻辑。
threads
使用async
,66
的值使用futures
返回。使用while
循环来尝试连续检查线程1和线程2的status
,以检查它们中的任何一个是否已经完成,在这种情况下,然后从任何一个线程获取最快的结果并在某些计算中使用。
目标:
1.在两个threads
中,检测其中哪一个最先返回66
的值
1.只要一个线程返回66
(不管另一个线程是否已经完成),返回值就在main()
中可用,以便对其执行一些进一步的简单运算
1.如果一个线程返回66
,并对main()
中的这个值执行算术运算,然后另一个线程随后也传递66
,则不应在任何计算中使用第二个返回值
**请注意:**在决定发布这个问题之前,我们已经咨询了以下资源:
1.How to check if thread has finished work in C++11 and above?
1.Using Multithreading two threads return same value with different inputs?
1.后台加载的C++线程
1.Future returned by a function
1.Start multiple threads and wait only for one to finish to obtain results
问题和当前产出:
目前,即使function1
中的代码速度慢得多(例如,function1
中有1000次迭代的for
循环和function1
中有10次迭代的for
循环),程序始终输出第一个完成的thread
是rf1
。这让我相信,我可能引入了某种blocking
行为?
节目尝试:
# include <future>
#include <iostream>
#include "unistd.h"
double function1() {
// Logic to retrieve _value
// ...
double _value = 66;
return _value;
}
double function2() {
// Logic to retrieve _value
// ...
double _value = 66;
return _value;
}
int main() {
double ret_value = 0;
auto rf1 = std::async(std::launch::async, function1);
auto status1 = rf1.wait_for(std::chrono::nanoseconds(1));
auto rf2 = std::async(std::launch::async, function2);
auto status2 = rf2.wait_for(std::chrono::nanoseconds(1));
while (true) {
if (status1 == std::future_status::ready) {
std::cout << "RF1 FINISHED FIRST" << std::endl;
// No longer need returned val from 2nd thread.
// Get result from 1st thread
ret_value = rf1.get();
break;
}
else if (status2 == std::future_status::ready) {
std::cout << "RF2 FINISHED FIRST" << std::endl;
// No longer need returned val from 1st thread.
// Get result from 2nd thread
ret_value = rf2.get();
break;
}
else if (status1 != std::future_status::ready) {
// RF1 not finished yet
status1 = rf1.wait_for(std::chrono::nanoseconds(1));
}
else if (status2 != std::future_status::ready) {
// RF2 not finished yet
status2 = rf2.wait_for(std::chrono::nanoseconds(1));
}
}
// Do some calculations on the quickest
// returned value
double some_value = ret_value + 40;
return 0;
}
问题:
**Q1.**是否可以通过任何方式修改程序以检测返回最快的thread
,以便在main()
中使用66
的返回值进行进一步计算?
q2.while
循环是否引入了任何类型的blocking
行为?
如果任何人能够提供建议或指出一些有助于解决这一困境的资源,我们将不胜感激。到目前为止,找到与此场景完全匹配的multithreading
文档一直是一个挑战。
编辑:
根据@jxh提供的有用答案,指示WHILE
循环继续等待的else if
条件已被删除,如下所示。
此外,还向function1
和function2
添加了一些逻辑,以确定哪一个将最先完成。如代码中所示,function1
具有98
迭代,function2
具有100
迭代,但输出仍然显示function2
已首先完成:
# include <future>
# include <iostream>
# include "unistd.h"
double function1() {
// Logic to retrieve _value
for (int i = 0; i < 98; i++) {
std::cout << std::endl;
}
double _value = 66;
return _value;
}
double function2() {
// Logic to retrieve _value
for (int i = 0; i < 100; i++) {
std::cout << std::endl;
}
double _value = 66;
return _value;
}
int main() {
double ret_value = 0;
auto rf1 = std::async(std::launch::async, function1);
auto status1 = rf1.wait_for(std::chrono::nanoseconds(1));
auto rf2 = std::async(std::launch::async, function2);
auto status2 = rf2.wait_for(std::chrono::nanoseconds(1));
while (true) {
if (status1 == std::future_status::ready) {
std::cout << "RF1 FINISHED FIRST" << std::endl;
// No longer need returned val from 2nd thread.
// Get result from 1st thread
ret_value = rf1.get();
break;
}
else if (status2 == std::future_status::ready) {
std::cout << "RF2 FINISHED FIRST" << std::endl;
// No longer need returned val from 1st thread.
// Get result from 2nd thread
ret_value = rf2.get();
break;
}
status1 = rf1.wait_for(std::chrono::nanoseconds(1));
status2 = rf2.wait_for(std::chrono::nanoseconds(1));
}
// Do some calculations on the quickest
// returned value
double some_value = ret_value + 40;
return 0;
}
1条答案
按热度按时间vojdkbi01#
while
内部代码中的逻辑将始终调用rf1.wait_for()
,直到其状态为Ready。由于您的
ready
检查将break
退出循环,因此您不需要使用else if
来决定是否进行进一步的等待。只需再做两次等待,就像进入while
之前一样。您已经更新了问题,并且更改了被调用函数的行为,而不是原来的行为。让我们笼统地谈一下这个问题,而不是讨论这些变化。
要解决接近终点,你可以使用蜂鸣器,就像他们在游戏节目中所做的那样。最先发出嗡嗡声的是一个明确的信号。我们可以用管道模拟蜂鸣器,而不是尝试实现真正的蜂鸣器。并且,该函数通过向管道写入一个值来嗡嗡作响。
然后,等待代码从管道中读取,并观察值。该值指示哪个函数最先完成,因此代码然后等待适当的将来来获取该值。
请注意,为简洁起见,示例代码省略了错误处理。