如何在parallel/future框架及pblapply并行过程中向R控制台输出消息
并行处理中输出消息的解决方案
一、用parallel包结合文件输出
Windows下PSOCK集群的子进程输出不会直接同步到主控制台,最简单的方式是让子进程把消息写入共享日志文件:
library(parallel) library(stringi) fun_func <- function(x){ # 指定日志文件路径,子进程都往这个文件追加内容 log_file <- "parallel_log.txt" cat(paste0("hello world ", x, "\n"), file = log_file, append = TRUE) return(paste0("hello world ", x)) } set.seed(23) d <- stri_rand_strings(100, 2, '[a-z]') names(d) <- d cl <- makeCluster(3) clusterExport(cl, c("fun_func")) res <- parLapply(cl, X = d, FUN = fun_func) stopCluster(cl) # 查看日志内容 readLines("parallel_log.txt") head(res)
二、用future框架直接输出到控制台
future框架对Windows的兼容性更好,配置后子进程的消息可以直接转发到主控制台:
library(future) library(furrr) library(stringi) # 配置多会话模式,适合Windows plan(multisession, workers = 3) fun_func <- function(x){ # 用message比cat更适合日志输出,转发更稳定 message(paste0("hello world ", x)) return(paste0("hello world ", x)) } set.seed(23) d <- stri_rand_strings(100, 2, '[a-z]') names(d) <- d # future_map会自动处理消息转发 res <- future_map(d, fun_func) head(res)
三、用ParallelLogger实现控制台+文件双输出
之前没成功可能是没给子进程同步logger配置,按下面的代码来:
library(ParallelLogger) library(parallel) library(stringi) # 创建同时输出到控制台和文件的logger logger <- createLogger( name = "parallel_logger", appenders = list( createConsoleAppender(), createFileAppender(fileName = "parallel_logger.txt") ) ) registerLogger(logger) fun_func <- function(x){ # 用ParallelLogger提供的logInfo函数写日志 logInfo(paste0("hello world ", x)) return(paste0("hello world ", x)) } set.seed(23) d <- stri_rand_strings(100, 2, '[a-z]') names(d) <- d cl <- makeCluster(3) # 把logger相关的函数和对象导出到所有子进程 clusterExport(cl, c("fun_func", "logger", "logInfo")) # 每个子进程都要注册logger才能生效 clusterEvalQ(cl, registerLogger(logger)) res <- parLapply(cl, X = d, FUN = fun_func) stopCluster(cl) # 用完后注销logger unregisterLogger("parallel_logger") head(res)
四、pblapply的替代方案:pbmcapply
如果偏好进度条+并行,pbmcapply是pbapply的改进版,支持Windows下的消息输出:
library(pbmcapply) library(stringi) fun_func <- function(x){ message(paste0("hello world ", x)) return(paste0("hello world ", x)) } set.seed(23) d <- stri_rand_strings(100, 2, '[a-z]') names(d) <- d # mc.cores指定并行核心数,自动显示进度条+消息输出 res <- pbmclapply(d, fun_func, mc.cores = 3) head(res)
内容的提问来源于stack exchange,提问作者ava
相关产品推荐
相关产品推荐

