【发布时间】:2018-04-30 17:11:57
【问题描述】:
因此,在下面的代码中,我使用std::thread() 报告程序进度,该示例已被更改为以不合理的间隔报告,并带有不具信息性的消息,以证明问题。
#include <Rcpp.h>
#include <thread>
#include <chrono>
#include <atomic>
using namespace Rcpp;
void reporter(const std::atomic<bool> &running) {
while (running) {
Rprintf( "Program running...\n" );
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
}
// [[Rcpp::export]]
void example() {
int i = 1;
std::atomic<bool> running{true};
std::thread reporter_thread(
[&] () { reporter(running); }
);
while (true) {
i++;
i--;
}
return;
}
在我的 2017 MacBook Pro 上,这会在第 93 次打印时触发 stack usage is too close to the limit 崩溃。如果我更改为 Rprintf,这也会崩溃,但据我所知,std::cout 是免疫的。
我可以更改代码,以便在父线程中进行打印,并在生成的线程中切换一个标志,这似乎也可以避免崩溃。
#include <Rcpp.h>
#include <thread>
#include <chrono>
#include <atomic>
using namespace Rcpp;
void reporter(const std::atomic<bool> &running, std::atomic<bool> &print_message) {
while (running) {
std::this_thread::sleep_for(std::chrono::microseconds(10));
print_message = true;
}
}
// [[Rcpp::export]]
void example() {
int i = 1;
std::atomic<bool> running{true};
std::atomic<bool> print_message{true};
std::thread reporter_thread(
[&] () { reporter(running, print_message); }
);
while (true) {
i++;
i--;
if (print_message)
Rprintf( "Program running...\n" );
print_message = false;
}
return;
}
所以我有两个问题:
- 为什么第一个版本会导致崩溃。
- 第二个版本能保证安全吗?
【问题讨论】:
-
如果你想在不允许 std::cout 的 CRAN 上发布,你可以考虑在一个像 spin_mutex 这样的简单互斥锁中保护你的 Rcout
标签: c++ r multithreading rcpp