通过 std::shared_ptr 使用 Rcpp 和 RcppParallel 的线程安全函数指针
Threadsafe function pointer with Rcpp and RcppParallel via std::shared_ptr
我想在 RcppPralel worker 中使用线程安全函数指针。但是我已经对这个小例子产生了疑问。无论我是在包中使用它并在 DESCRIPTION 文件中添加 SystemRequirements: C++11
,还是在标准 cpp 文件中使用它并添加 // [[Rcpp::plugins(cpp11)]]
我都会得到相同的 错误:'shared_ptr' 不是 'std' 的成员。谁能帮帮我吗?谢谢!
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;
double f1 (double x, double y) {
return x * y;
}
double f2 (double x, double y) {
std::shared_ptr<int> p1;
std::cout << "p1: " << p1.use_count() << '\n';
return x + y;
}
typedef double (*funcPtr)(double x, double y);
std::shared_ptr<funcPtr> selectf(std::string abc) {
std::shared_ptr<funcPtr> fp = NULL;
if(abc == "a"){
fp = std::make_shared<funcPtr>(new funcPtr(&f1));
}else {
fp = std::make_shared<funcPtr>(new funcPtr(&f2));
}
return fp;
}
// [[Rcpp::export]]
double f0(double x, double y, std::string abc){
double ret;
df = selectf(abc);
ret = df(x, y);
return(ret);
}
/*** R
if(FALSE){
f0(10, 10, "a")
}
*/
系统信息:
> sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=German_Germany.1252
[2] LC_CTYPE=German_Germany.1252
[3] LC_MONETARY=German_Germany.1252
[4] LC_NUMERIC=C
[5] LC_TIME=German_Germany.1252
attached base packages:
[1] stats graphics grDevices utils datasets
[6] methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.0 R6_2.2.2 magrittr_1.5
[4] tools_3.5.0 withr_2.1.2 roxygen2_6.0.1
[7] yaml_2.1.19 memoise_1.1.0 Rcpp_0.12.18
[10] xml2_1.2.0 stringi_1.2.2 stringr_1.3.1
[13] digest_0.6.15 commonmark_1.5 devtools_1.13.5
std::shared_ptr
在 header <memory>
中声明。尝试:
#include <memory>
您可以找到它的文档 here。
前面的回答已经告诉你#include <memory>
;在后续中,您声称基本示例不起作用——它对我有用。
但首先要澄清一点:所有 跨调用添加(编译)函数的内存管理必须通过 R 的内存管理进行。这就是 Rcpp 所做的,也是 Rcpp 文档的内容。现在,对于多线程代码,我们在 RcppParalllel 中有 RMatrix
和 RVector
,因为我们 cannot 从多线程代码中干扰 R 的内存管理(及其单线程模式);有关详细信息,请参阅 RcppParallel 的优秀文档。
就是说,如果您确定要 shared_ptr
在定义的范围内,您可以。这也是基于您链接的示例的工作副本。
代码
#include <memory>
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
struct C { int* data; };
// [[Rcpp::export]]
bool foo() {
std::shared_ptr<int> p1;
std::shared_ptr<int> p2 (nullptr);
std::shared_ptr<int> p3 (new int);
std::shared_ptr<int> p4 (new int, std::default_delete<int>());
std::shared_ptr<int> p5 (new int, [](int* p){delete p;}, std::allocator<int>());
std::shared_ptr<int> p6 (p5);
std::shared_ptr<int> p7 (std::move(p6));
std::shared_ptr<int> p8 (std::unique_ptr<int>(new int));
std::shared_ptr<C> obj (new C);
std::shared_ptr<int> p9 (obj, obj->data);
Rcpp::Rcout << "use_count:\n";
Rcpp::Rcout << "p1: " << p1.use_count() << '\n';
Rcpp::Rcout << "p2: " << p2.use_count() << '\n';
Rcpp::Rcout << "p3: " << p3.use_count() << '\n';
Rcpp::Rcout << "p4: " << p4.use_count() << '\n';
Rcpp::Rcout << "p5: " << p5.use_count() << '\n';
Rcpp::Rcout << "p6: " << p6.use_count() << '\n';
Rcpp::Rcout << "p7: " << p7.use_count() << '\n';
Rcpp::Rcout << "p8: " << p8.use_count() << '\n';
Rcpp::Rcout << "p9: " << p9.use_count() << '\n';
return true;
}
使用
R> Rcpp::sourceCpp("/tmp/soExample.cpp")
R> foo()
use_count:
p1: 0
p2: 0
p3: 1
p4: 1
p5: 2
p6: 0
p7: 2
p8: 1
p9: 2
[1] TRUE
R>
我想在 RcppPralel worker 中使用线程安全函数指针。但是我已经对这个小例子产生了疑问。无论我是在包中使用它并在 DESCRIPTION 文件中添加 SystemRequirements: C++11
,还是在标准 cpp 文件中使用它并添加 // [[Rcpp::plugins(cpp11)]]
我都会得到相同的 错误:'shared_ptr' 不是 'std' 的成员。谁能帮帮我吗?谢谢!
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;
double f1 (double x, double y) {
return x * y;
}
double f2 (double x, double y) {
std::shared_ptr<int> p1;
std::cout << "p1: " << p1.use_count() << '\n';
return x + y;
}
typedef double (*funcPtr)(double x, double y);
std::shared_ptr<funcPtr> selectf(std::string abc) {
std::shared_ptr<funcPtr> fp = NULL;
if(abc == "a"){
fp = std::make_shared<funcPtr>(new funcPtr(&f1));
}else {
fp = std::make_shared<funcPtr>(new funcPtr(&f2));
}
return fp;
}
// [[Rcpp::export]]
double f0(double x, double y, std::string abc){
double ret;
df = selectf(abc);
ret = df(x, y);
return(ret);
}
/*** R
if(FALSE){
f0(10, 10, "a")
}
*/
系统信息:
> sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=German_Germany.1252
[2] LC_CTYPE=German_Germany.1252
[3] LC_MONETARY=German_Germany.1252
[4] LC_NUMERIC=C
[5] LC_TIME=German_Germany.1252
attached base packages:
[1] stats graphics grDevices utils datasets
[6] methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.0 R6_2.2.2 magrittr_1.5
[4] tools_3.5.0 withr_2.1.2 roxygen2_6.0.1
[7] yaml_2.1.19 memoise_1.1.0 Rcpp_0.12.18
[10] xml2_1.2.0 stringi_1.2.2 stringr_1.3.1
[13] digest_0.6.15 commonmark_1.5 devtools_1.13.5
std::shared_ptr
在 header <memory>
中声明。尝试:
#include <memory>
您可以找到它的文档 here。
前面的回答已经告诉你#include <memory>
;在后续中,您声称基本示例不起作用——它对我有用。
但首先要澄清一点:所有 跨调用添加(编译)函数的内存管理必须通过 R 的内存管理进行。这就是 Rcpp 所做的,也是 Rcpp 文档的内容。现在,对于多线程代码,我们在 RcppParalllel 中有 RMatrix
和 RVector
,因为我们 cannot 从多线程代码中干扰 R 的内存管理(及其单线程模式);有关详细信息,请参阅 RcppParallel 的优秀文档。
就是说,如果您确定要 shared_ptr
在定义的范围内,您可以。这也是基于您链接的示例的工作副本。
代码
#include <memory>
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
struct C { int* data; };
// [[Rcpp::export]]
bool foo() {
std::shared_ptr<int> p1;
std::shared_ptr<int> p2 (nullptr);
std::shared_ptr<int> p3 (new int);
std::shared_ptr<int> p4 (new int, std::default_delete<int>());
std::shared_ptr<int> p5 (new int, [](int* p){delete p;}, std::allocator<int>());
std::shared_ptr<int> p6 (p5);
std::shared_ptr<int> p7 (std::move(p6));
std::shared_ptr<int> p8 (std::unique_ptr<int>(new int));
std::shared_ptr<C> obj (new C);
std::shared_ptr<int> p9 (obj, obj->data);
Rcpp::Rcout << "use_count:\n";
Rcpp::Rcout << "p1: " << p1.use_count() << '\n';
Rcpp::Rcout << "p2: " << p2.use_count() << '\n';
Rcpp::Rcout << "p3: " << p3.use_count() << '\n';
Rcpp::Rcout << "p4: " << p4.use_count() << '\n';
Rcpp::Rcout << "p5: " << p5.use_count() << '\n';
Rcpp::Rcout << "p6: " << p6.use_count() << '\n';
Rcpp::Rcout << "p7: " << p7.use_count() << '\n';
Rcpp::Rcout << "p8: " << p8.use_count() << '\n';
Rcpp::Rcout << "p9: " << p9.use_count() << '\n';
return true;
}
使用
R> Rcpp::sourceCpp("/tmp/soExample.cpp")
R> foo()
use_count:
p1: 0
p2: 0
p3: 1
p4: 1
p5: 2
p6: 0
p7: 2
p8: 1
p9: 2
[1] TRUE
R>