【问题标题】:Why does Rcout and Rprintf cause stack limit error when multithreading?为什么多线程时Rcout和Rprintf会导致栈限制错误?
【发布时间】: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;
}

所以我有两个问题:

  1. 为什么第一个版本会导致崩溃。
  2. 第二个版本能保证安全吗?

【问题讨论】:

  • 如果你想在不允许 std::cout 的 CRAN 上发布,你可以考虑在一个像 spin_mutex 这样的简单互斥锁中保护你的 Rcout

标签: c++ r multithreading rcpp


【解决方案1】:

关于你的第一个例子Writing R Extensions 不得不说:

从线程代码调用任何 R API 是“仅供专家使用”:他们需要阅读源代码以确定它是否是线程安全的。特别是,不得从线程代码中调用使用堆栈检查机制的代码。

我不会在线程代码中调用 R API 函数。我不确定你的第二个例子,但会首先寻找现有的解决方案,例如http://gallery.rcpp.org/articles/using-rcppprogress/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 2012-07-14
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多