creating an RInside instance inside a thread - c++

I am interested in writing a c++ program that is capable of running R scripts. For several design reasons I would like to create an instance of RInside, execute a script, grab the result, and destroy the instance; all within a thread. I know that R is not multi-threaded, and that one cannot create multiple instances of RInside. But can I create single instances within isolated threads? When I attempt to do this my code compiles, but I get the following error at run-time:
Error: C stack usage is too close to the limit
Error: C stack usage is too close to the limit
terminate called after throwing an instance of 'Rcpp::binding_not_found'
what(): binding not found: '.AutoloadEnv'
Aborted
Here is the code that produced the error:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <RInside.h>
void *thread_main(void *args){
RInside R(0,NULL);
/* hope to execute an R script here */
printf("--printing from thread--\n");
return NULL;
}
int main(int argc, char *argv[]){
pthread_t tid;
if( pthread_create(&tid, NULL, thread_main, NULL) ){
printf("failed to create thread\n");
return -1;
}
sleep(1);
return 0;
}
I have tried setting R_CStackLimit = (uintptr_t)-1 as recommended in Writing R Extension, but to no avail.
I am running ubuntu, R version 2.15.2, RInside version 0.2.10.
Is it possible to accomplish this? or do I have to learn something like Rserve?
Thank you so much!

R is, and will likely remain, single-threaded. RInside goes to some length to ensure it is created as a singleton; if you subvert that you get the errors you see above. Within the same executable, you only get one RInside instance so one-per-thread will not work. As you experienced.
See the examples I include in the source on how to cope with the single-threaded backend when using multi-threaded frontends such as Qt or the Wt library for webapps.
Longer term we may be able to do what Rserve does and fork. Code contributions would be welcome, I probably won't have time to work on this.

Related

How to force user logoff on Ubuntu using C++?

Is there any way to force user log out using C++ in Ubuntu (16.04 or 18.04)? Like if condition is met, I want the program to log out the current user.
In windows 10 we can probably use ExitWindows like this https://learn.microsoft.com/en-us/windows/desktop/shutdown/how-to-log-off-the-current-user.
Is it possible in Ubuntu? I couldn't find a good example how to do it.
This is window-manager specific, so it's probably easiest to use an exec function to do it. Ubuntu 18.04 by default uses Gnome, so in Gnome you would do the following:
#include <unistd.h>
#include <stdlib.h>
int main()
{
if (execl("/usr/bin/gnome-session-quit", "/usr/bin/gnome-session-quit",
"--no-prompt", (char*) NULL) < 0)
printf("Failed to logout\n");
}
I'm not exactly sure where the loginctl program is located for KDE, so I'll assume it's in the same location, so for KDE you would:
#include <stdlib.h>
...
char *user=getenv("USER");
if (execl("/usr/bin/loginctl", "/usr/bin/loginctl",
user, (char*) NULL) < 0)
printf("Failed to logout\n");
You can invoke any operating system command using c++ system() from stdlib.h.
#include<stdlib.h>
int main(){
system("gnome-session-quit"); //logs out.
}
To my knowledge after the above code is executed in ubuntu, it logs out automatically after 60 seconds if there is any unsaved work.

Compiling Julia embedded in C++ code

I'm trying to compile the following C++ code
#include <julia.h>
int main(int argc, char *argv[])
{
/* required: setup the julia context */
jl_init(NULL);
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook();
return 0;
}
I compile the code using
gcc -I/usr/include/julia -L/usr/lib/x86_64-linux-gnu/julia -ljulia juliatest.cpp -o test
I get the following error-
juliatest.cpp:19:20:: error: too few arguments to function ‘void jl_atexit_hook(int)’
jl_atexit_hook();
^
In file included from juliatest.cpp:1:0:
/usr/include/julia/julia.h:1188:16: note: declared here
DLLEXPORT void jl_atexit_hook(int status);
^
If I remove jl_atexit_hook(); from the code, I get the following errors-
juliatest.cpp:(.text+0x1a): undefined reference to `jl_init_with_image'
juliatest.cpp:(.text+0x24): undefined reference to `jl_eval_string'
What am I doing wrong?
The example you are trying to compile is a little bit outdated. As already mentioned you need to give an exitcode to the jl_atexit_hook()
function. The linker message is about missing functions defined in libraries. To get rid of distribution details I downloaded and build the tarball. Now the example can be build using this makefile:
JULIA_DIR:=julia-0.4.2
JULIA_LIB:=$(JULIA_DIR)/usr/lib
JULIA_SRC:=$(JULIA_DIR)/src
JULIA_INC:=$(JULIA_DIR)/usr/include
CPPFLAGS:=-I$(JULIA_INC) -I$(JULIA_SRC) -I$(JULIA_SRC)/support
LDFLAGS:=-L$(JULIA_LIB)
LDLIBS=-ljulia
export LD_LIBRARY_PATH:=$(JULIA_LIB):$(JULIA_LIB)/julia
all: main
run: main
#./main
clean:
rm -f main
If you now type make run you will get the next error message about a wrong path the system image is searched in. As Thomas noted here the function jl_init() is creating a context that may fail in this case. We shall give the name and the path of the system image to the init function using jl_init_with_image("julia-0.4.2/usr/lib/julia", "sys.so") instead. This is an ugly hard coded path and can surely be replaced. But for getting started with this example and to get this problem known, it is enough. The corrected example is this:
#include <julia.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
/* required: setup the julia context */
jl_init_with_image("julia-0.4.2/usr/lib/julia", "sys.so");
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook(0);
putchar('\n');
return 0;
}
Running make run will now be a quite complicated way to calculate the square root of 2 :-)
Have fun.

How to initialize and load MCR

I incorporated C++ shared library generated from MATLAB in a Win32 console application. The MATLAB program takes 2-3 sec to execute in MATLAB but the console application takes 11-12 seconds to execute. I read this is because of the start up time of MCR and I believe after the MCR is initialized it must take same time as it takes in matlab. So how can I load or initialize the MCR so that it is always in the RAM or cache so that it will take 2-3 sec for the console application to run? Should I have to make an infinity loop so that the MCR is loaded continously?? I am working on Windows OS and I am calling the console application from PHP. Any tutorials or link for that?
I have added the MCR_CACHE_ROOT as an environment variable which points to a folder(not temporary). My console application code is as follows:
// shoes_shared.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "shoes_sharedlibrary.h"
#include <iostream>
#include <string.h>
#include "mex.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
/* Call the MCR and library initialization functions */
//const char *pStrings[]={"-nojvm","-nojit"};
// if (!mclInitializeApplication(pStrings,2))
// {
// fprintf(stderr, "Could not initialize MCR for the application.\n");
// return -1;
// }
if (!shoes_sharedlibraryInitialize())
{
exit(1);
}
mwArray img(argv[1]);
double wt1 = _tstof(argv[2]);
mwArray C(wt1);
double wt2 = _tstof(argv[3]);
mwArray F(wt2);
double wt3 = _tstof(argv[4]);
mwArray T(wt3);
double wt4 = _tstof(argv[5]);
mwArray S(wt4);
test_shoes(img,C,F,T,S);
//shoes_sharedlibraryTerminate();
//mclTerminateApplication();
return 0;
}
I have commented the lines above thinking that it will make it faster but no luck. Any help?
Are you running in debug or release? If you are running in debug, try running in release and see if that solves your problem. Are you using Visual Studio? If so, try opening the modules window there you will see a list of loaded dlls. Check and see if your library is being constantly loaded and unloaded, or if it is loaded once and stays loaded.
I don't know on which vm matlab is running, but for example the JVM there is Nailgun, a Java server that runs in the backgroud and can be called whenever some java applications need to be executed. I know that Matlab uses Java, but I am not shure wheather your DLL still invokes it. So if it does, that might be the problem.
Try to put MCR and all shared library dependencies to RAM drive.
There are lot of ways to create RAM drive. I would suggest to use ImDisk

Why C-forkbombs don't work like bash ones?

If I run the classical bash forkbomb:
:(){ :&:&};:
my system hangs after a few seconds.
I tried to write a forkbomb in C, here is the code:
#include <unistd.h>
int main( )
{
while(1) {
fork();
}
return 0;
}
When I run it the system gets less responsive, but I can kill that process (even after minutes) just pressing ^C.
The above code is different from the original bash forkbomb I posted: it's something more like:
:( )
{
while true
do
:
done
}
(I didn't test it; don't know if it'd hang the system).
So I also tried to implement the original version; here the code:
#include <unistd.h>
inline void colon( const char *path )
{
pid_t pid = fork( );
if( pid == 0 ) {
execl( path, path, 0 );
}
}
int main( int argc, char **argv )
{
colon( argv[0] );
colon( argv[0] );
return 0;
}
But still nothing: I can run it and then easily kill it. It's not hanging my system.
Why?
What's so special about bash forkbombs? Is it because bash uses a lot more memory/CPU? Because bash processes call a lot more system calls (eg, to access filesystem) than mine?
That C program is tiny, seriously tiny. In addition, fork()'ing a program like that is very, very efficient. An interpreter, such as Bash, however, is much more expensive in terms of RAM usage, and needs to access the disk all the time.
Try running it for much longer. :)
The real cause for this is that in BASH the process you create is detached from the parent. If the parent process (the one you initially started) is killed, the rest of the processes live on. But in the C implementations you listed the child processes die if the parent is killed, so it's enough to bring down the initial process you started to bring down the whole tree of ever-forking processes.
I have not yet come up with a C forkbomb implementation that detaches child processes so that they're not killed if the parent dies. Links to such implementations would be appreciated.
In your bash forkbomb, you are putting new processes in new background process groups, so you are not going to be able to ^C them.
Thats basically because of the size.
When you are running the bash fork bomb it loads big monster programs into memory (with respect to your c program) each of them start hogging on your cpu resources.Definitely when big monsters start reproducing trouble comes more quickly than if bees start doing the same.
So the computer hangs immediately.However if you keep your c executable running for long it will hang the system too.Just that the time will be much much more.
If you want to compare the size of bash with size of c program check out /proc//status.
first with pid of any running instance of bash,and then with pid of any running instance of a c program

Do other tasks while a system() command is being executed

I have this c++ program that is doing a simple ping on a specified ip address. I am not into networking so i'm just using the system() command in c++ to execute the ping from a shell and store the results in a file, that's easy.
The problem is that i want some dots to be printed on the screen while the system() command is being executed. i tried with:
while(system(cmd))
{
//execute the task here
}
but no success. I think that i should create threads or something.
Can you help me ? What exactly i am supposed to do in order to get this done as i want to ?
The problem with system is that it suspends execution until completion. On unix systems you will need to use a sequence of fork, execv, dup2 and pipe. This will allow you to do something more useful. See http://docs.linux.cz/programming/c/unix_examples/execill.html for an example.
You need to create a forked process using fork, like this, and using popen to read the input from the output of the command ping google.com and process it accordingly. There is an interesting guide by Beej on understanding the IPC mechanisms which is included in the code sample below...
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int rv;
FILE *ping;
char buf[2000];
switch(pid = fork()) {
case -1:
perror("fork"); /* something went wrong */
exit(1); /* parent exits */
case 0:
// We're the child
ping = popen("ping google.com", "r");
if (ping != NULL){
fgets(buf, sizeof(buf), ping);
pclose(ping);
rv = 0;
}else{
perror("popen failed");
rv = -1;
}
exit(rv);
default:
// We're the parent...
wait(&rv);
}
// Now process the buffer
return 0;
}
Hope this helps,
Best regards,
Tom.
Edit On consideration, I believe that popen is the way to go with or without output from cmd.
Older
You are probably looking for something in the wait (2) family of commands plus a fork and exec.
From the manual page
The wait() function suspends execution of its calling process until
stat_loc information is available for a terminated child process, or a
signal is received. On return from a successful wait() call, the
stat_loc area contains termination information about the process that
exited as defined below.
Or if cmd returns some progress information you want popen (3) which is discussed in a number of existing SO questions; for instance How can I run an external program from C and parse its output?.
If you are on a unix system, you can start a command with an & to indicate that it runs in the background like this: myscript &
This will start a new process separate from the current program. You need to pick up the process number (hopefully from system, my c posix api knowledge is rusty) and then check up on it probably with a call to something like wait or waitpid with non-blocking turned on.
This is complicated for a beginner -- I'll let someone else post details if still interested.