Running two programs concurrently - c++

I have two C++ programs built in Ubuntu, and I want to run them concurrently. I do not want to combine them into one C++ project and run each on a different thread, as this is causing me all sorts of problems.
The solution I effectively want to emulate, is when I open two tabs in the terminal, and run each program in a separate tab. However, I also want one program (let's call this Program A) to be able to quit and rerun the other program (Program B). This cannot be achieved just in the terminal.
So what I want to do is to write some C++ code in Program A, which can run and quit Program B at any point. Both programs must run concurrently, so that Program A doesn't have to wait until Program B returns before continuing on with Program A.
Any ideas? Thanks!

In Linux you can fork the current process, which creates a new process.
Then you have to launch the new process with some exec system call.
Refer to:
http://man7.org/linux/man-pages/man2/execve.2.html
For example:
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */
int main(int argc,char** argv)
{
pid_t pid=fork();
if (pid==0)
{
execv("/bin/echo",argv);
}
}

You have multiple options here:
The traditional POSIX fork / exec (there are literally tons of examples on how to do this in SO, for example this one).
If you can use Boost then Boost process is an option.
If you can use Qt then QProcess is an option.
Boost and Qt also provide nice means manipulating the standard input/output of the child process if this is important. If not the classical POSIX means should do fine.

Take a look at the Linux operating system calls, fork() and exec(). The fork() call will create two copies of the current process which continue to execute simultaneously.
In the parent process, fork()'s return value is the PID (process ID) of
the child process.
In the child process, fork()'s return value is 0.
On error, fork()'s return value is -1.
You can use this to your advantage to control the behavior of the parent and child. As an example:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc,char** argv)
{
char* progB = "/bin/progB";
char* args[progName, "arg1", "arg2", ..., NULL];
char* env[NULL]; // can fill in environment here.
pid_t pid=fork();
if (pid==0)
{
// In child...
execv(progB, args, env);
}
else if (pid == -1)
{
// handle error...
}
else
{
// In parent; pid is the child process.
// can wait for child or kill child here.
}
}
To wait until your child exits (in the third case above), you can use wait(2), which returns your child pid on successful termination or -1 on error:
pid_t result = waitpid(pid, &status, options);
To kill your child preemptively, you can send a kill signal as described in kill(2):
int result = kill(pid, SIGKILL); // or whatever signal you wish
This should allow you to manage your processes as described in the original question.

Related

C++ how to pass command line args between processes?

I have a parent process that needs to send it is command line args to the its child? How I can do this? I mean from parent.cpp to child .cpp?
Thanks
POSIX (Linux) solution:
Use execvp(const char *file, char *const argv[]) to run a programme with arguments in place of the current programme. The argv[] that you pass as reference, follows the same logic than the argv[] parameter passing in main().
If you want to keep your current process running and launch the new programme in a distinct process, then you have first to fork(). The rough idea is something like:
pid_t pid = fork(); // creates a second process, an exact copy of the current one
if (pid==0) { // this is exectued in the child process
char **argv[3]{".\child","param1", NULL };
if (execvp(argv[0], argv)) // execvp() returns only if lauch failed
cout << "Couldn't run "<<argv[0]<<endl;
}
else { // this is executed in the parent process
if (pid==-1) //oops ! This can hapen as well :-/
cout << "Process launch failed";
else cout << "I launched process "<<pid<<endl;
}
Windows solution
The easiest windows alternative is to use the ms specific _spawnvp() or similar functions. It takes same arguments as the exec version, and the first parameters tells if you want to:
replace the calling process (as exec in posix)
create a new process and keep the calling one (as fork/exec combination above)
or even if you want to suspend the calling process until the child process finished.
If fork() is used, then the child process inherits from the parent process.
http://man7.org/linux/man-pages/man2/fork.2.html
If you mean just passing variables between instances of objects in memory, then you'd create variables for int argc and char * argv[] to pass along.
In parent. Use
system("child_application my arg list");
In child. Use
int main(int argc, char *argv[])
For easy parsing args try boost program_options library.
In unix system can use fork. Child process get all parent memory.

C++ thread still alive after kill?

I have an issue: I create a thread to execute a command line and sometimes it takes a lot of time for waiting. So, I want to kill this thread and I implement below code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
void* doSomeThing(void *)
{
cout<<"Begin execute"<<endl;
system("svn info http://wrong_link_it's_take_a_lot_of_time_to_execute");
return NULL;
}
int main() {
pthread_t myThread;
int err = pthread_create(&myThread,NULL, &doSomeThing,NULL);
if(err != 0)
{
cout<<"Create thread not success"<<endl;
}
sleep(2);
if(pthread_cancel(myThread) == 0)
{
cout<<"Thread was be kill"<<endl;
}
sleep(3);
cout<<"End of program";
return 0;
}
I'm using pthread_cancel to kill this thread and the line cout<<"Thread was be kill"<<endl; always appear after I execute. It is meant this thread being killed, but I saw the surprise result when I ran it on Eclipse (both on Ubuntu and Windows 7)
Anybody can explain to me why this thread still alive after kill and can you give me some method to resolve this issue.
Thank you.
cancelling a thread is not actually killing it. it just requests cancellation:
pthread_cancel - send a cancellation request to a thread
(from man pthread_cancel).
The pthread_cancel() function sends a cancellation request to the
thread thread. Whether and when the target thread reacts to the
cancellation
request depends on two attributes that are under the control of that thread: its cancelability state and type.
As pointed out by Marcus Müller in his answer, pthread_cancel() not necessarily ends the thread addressed.
Do not use system() if you want to kill what had been run.
Create your own new child process using fork()/exec*().
If it's time to end the child let the parent issue a kill() on the PID returned by fork()ing in 1.

Using pipes to communicate with children in multithreaded programs

I am trying to use fork to execute child programs from a multithreaded parent using code similar to:
#include <thread>
#include <unistd.h>
#include <vector>
#include <sys/wait.h>
void printWithCat(const std::string& data) {
std::vector<char*> commandLine;
// exec won't change argument so safe cast
commandLine.push_back(const_cast<char*>("cat"));
commandLine.push_back(0);
int pipes[2];
pipe(pipes);
// Race condition here
pid_t pid = fork();
if (pid == 0) {
// Redirect pipes[0] to stdin
close(pipes[1]);
close(0);
dup(pipes[0]);
close(pipes[0]);
execvp("cat", &commandLine.front());
}
else {
close(pipes[0]);
write(pipes[1], (void*)(data.data()), data.size());
close(pipes[1]);
waitpid(pid, NULL, 0);
}
}
int main()
{
std::thread t1(printWithCat, "Hello, ");
std::thread t2(printWithCat, "World!");
t1.join();
t2.join();
}
This code contains a race condition between the call to pipe and the call to fork. If both threads create pipes and then fork, each child process contains open file descriptors to both pipes and only close one. The result is that a pipe never gets closed and the child process never exits. I currently wrap the pipe and fork calls in a global lock but this adds an additional synchronisation. Is there a better way?
Don't think you're avoiding synchronization by avoiding a lock in your code -- the kernel is going to take locks for process creation anyway, probably on a far more global level than your lock.
So go ahead and use a lightweight mutex here.
Your problems are going to arise when different parts of the program make fork calls and don't agree on a single mutex (because some are buried in library code, etc)

How to create a process in C++ under Linux?

I'd like to create a process by calling a executable, just as popen would allow. But I don't want to actually communicate through a pipe with it: I want to control it, like sending signals there or find out if the process is running, wait for it to finish after sending SIGINT and so on, just like multiprocessing in Python works. Like this:
pid_t A = create_process('foo');
pid_t B = create_process('bar');
join(B); // wait for B to return
send_signal(A, SIGINT);
What's the proper way to go?
Use case for example:
monitoring a bunch of processes (like restarting them when they crash)
UPDATE
I see in which direction the answers are going: fork(). Then I'd like to modify my use case: I'd like to create a class which takes a string in the constructor and is specified as follows: When an object is instantiated, a (sub)process is started (and controlled by the instance of the class), when the destructor is called, the process gets the terminate signal and the destructor returns as soon as the process returned.
Use case now: In a boost state chart, start a process when a state is entered, and send termination when the state has been left. I guess, http://www.highscore.de/boost/process/process/tutorials.html#process.tutorials.start_child is the thing that comes closest to what I'm looking for, excpet that it seems outdated.
Isn't that possible in a non-invasive way? Maybe I have a fundamental misunderstanding and there is a better way to do this kind of work, if so I'd be glad to get some hints.
UPDATE 2
Thanks to the answers below, I think I got the idea a little bit. I thought, this example would print "This is main" three times, once for the "parent", and once for each fork() – but that's wrong. So: Thank you for the patient answers!
#include <iostream>
#include <string>
#include <unistd.h>
struct myclass
{
pid_t the_pid;
myclass(std::string the_call)
{
the_pid = fork();
if(the_pid == 0)
{
execl(the_call.c_str(), NULL);
}
}
};
int main( int argc, char** argv )
{
std::cout << "This is main" << std::endl;
myclass("trivial_process");
myclass("trivial_process");
}
The below is not a realistic code at all, but it gives you some idea.
pid_t pid = fork()
if (pid == 0) {
// this is child process
execl("foo", "foo", NULL);
}
// continue your code in the main process.
Using the previously posted code, try this:
#include <signal.h>
#include <unistd.h>
class MyProc
{
public:
MyProc( const std::string& cmd)
{
m_pid = fork()
if (pid == 0) {
execl(cmd.c_str(), cmd.c_str(), NULL);
}
}
~MyProc()
{
// Just for the case, we have 0, we do not want to kill ourself
if( m_pid > 0 )
{
kill(m_pid, SIGKILL);
wait(m_pid);
}
}
private:
pid_t m_pid;
}
The downside I see on this example will be, you can not be sure, the process has finished (and probably he will not) if the signal is emitted, since the OS will continue after the kill immediately and the other process may get it delayed.
To ensure this, you may use ps ... with a grep to the pid, this should work then.
Edit: I have added the wait, which cames up in a comment up there!
Have a look to fork() (man 2 fork)

pipe fork and execvp analogs in windows

This is simple demonstration of pipe fork exec trio using in unix.
#include <stdio.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int outfd[2];
if(pipe(outfd)!=0)
{
exit(1);
}
pid_t pid = fork();
if(pid == 0)
{
//child
close(outfd[0]);
dup2(outfd[1], fileno(stdout));
char *argv[]={"ls",NULL};
execvp(argv[0], (char *const *)argv);
throw;
}
if(pid < 0)
{
exit(1);
}
else
{
//parrent
close(outfd[1]);
dup2(outfd[0], fileno(stdin));
FILE *fin = fdopen(outfd[0], "rt");
char *buffer[2500];
while(fgets(buffer, 2500, fin)!=0)
{
//do something with buffer
}
}
return 0;
}
Now I want to write same in windows using WinAPI. What functions should I use? Any ideas?
fork() and execvp() have no direct equivalent in Windows. The combination of fork and exec would map to CreateProcess (or _spawnvp if you use MSVC). For the redirection, you need CreatePipe and DuplicateHandle, this is covered decently in this MSDN article
If you only need fork+execvp in the sense of launching another process that reads from a pipe (like in your example) then the answer given by Erik is 100% what you want (+1 on that).
Otherwise, if you need real fork behaviour, you are without luck under Windows, as there is no such thing. Though, with a lot of hacks it can be achieved, kind of. Cygwin has a working fork implementation that creates a suspended process and abuses setjmp and shared memory to get hold of its context and manually copy the stack and heap over in a somewhat complicated "dance" between parent and child. It's far from pretty and not overly efficient, but it kind of works, and it is probably as good as it can get under an operating system that doesn't natively support it.