C++ - fork() and its return value - c++

I'm having troubles with this simple exercise. Here is the code:
int main(int argc, char** argv) {
pid_t pid1,pid2,pid3;
int a=5,b=4,c=3,retval,retval2;
pid1=fork();
if(pid1==0){
pid3=fork();
if(pid3==0)
exit(a);
else if(pid3>0){
waitpid(pid2,&retval2,0);
cout<<WEXITSTATUS(retval2);
}
}
else if(pid1>0){
pid2=fork();
if(pid2==0){
cout<<"CIAO";
exit(b);
}
else if(pid2>0){
waitpid(pid3,&retval,0);
cout<<WEXITSTATUS(retval);
}
}
return 0; }
As you can see it's not that complicated. All I want to do is pid2(father) to print pid3(son) return value and pid3(father) to print pid2(son) return value. Any advice? I would appreciate it very much.

Because of the first fork (the one that sets pid1), the second forks run in different processes. In the pid1==0 branch, pid2 never gets a value, because that process never assigns it one. Likewise, in the pid1>0 branch, pid3 never gets a value.
It looks like you're expecting the two processes to share the same set of variables, but it doesn't work like that. Forking creates two independent processes, each with its own copy of all its variables.

In your program, pid1 and pid3 are children of the original process (let's call it pid0), pid2 is the child of pid1.
Variables pid1, pid2 etc are only updated in specific processes, and left unitialized in the others. Waiting for pid3 in any other process than pid0 for instance does not make sense, because other processes won't have pid3 correctly set. Furthermore, waiting for a process which isn't a child of the current process doesn't work.
Also, the wait syscall takes a pointer as its parameter for the terminated child process return value. Doing a wait(pid2) is incorrect.
Now, to get the result you want, you'll have to set some kind of communication channel between pid1 and pid0, so that they may transmit to each other the return code of their respective child. A pipe created in pid0 might do the trick.
System call references:
wait
pipe

Related

Should we use exit or return in child process

Saying that I have used fork to create one child process. Here is an example:
pid_t pid=fork();
if (pid==0) /* child */
{
// do something
exit(0); // _exit, exit or return????
}
else /* parrent */
{
wait(nullptr);
return 0;
}
I've seen many examples of fork. Some of them used _exit to terminate the child process to avoid flush the I/O buffer, others used exit to terminate the child process. But non of them used return. As my understanding, _exit and exit won't call destructors automatically, so is it better to call return instead of exit in the child process? Or because all examples that I've ever seen are C, instead of C++, so they don't need to worry about destructors?
You can use either _exit or exit, but you shouldn't use return. When you fork a child, you retain the entire call stack as part of forking the child. So if you use return, you end up returning up all the way through your program, potentially continuing on and performing other tasks, which is almost certainly not what you want.
For example, if you have something like this snippet:
int get_value()
{
pid_t pid;
if (!(pid = fork())) {
int x = 0;
// do something with x.
exit(x);
}
else {
int status;
wait(&status);
return status;
}
}
int main()
{
int value = get_value();
switch (get_value()) {
case 0:
// call f
break;
case 255 << 8:
// call g
break;
}
}
you'll could end up calling f or g or doing other work with return, which is definitely not desired.
If you call _exit, functions that are registered with atexit are not called. This is the right thing to do in threaded environments. If you're not working in a threaded environment and you don't have any handlers registered with atexit, then they should be functionally equivalents.
If you want destructors in your child process to be called, put the child process code in its own function and let its variables be automatically destroyed when they go out of scope. exit will not destroy objects for you, which is good because usually you do not want to destroy objects created in the parent process in your child process.
You could use return if you are looking for an exit code of the child process, just to say the process ran and executed correctly/not. Same as you do with your main function in a program. Otherwise just use exit to stop the process from running any further.
fork will copy the whole process, its not equivalent to launching a thread with a new main function.
Returning will simply return from the current function and the execution of the child will continue in the enclosing function.
So in you snippet you have to terminate the child or it will "escape". You can do that by calling exit() or std::terminate(). No destructors are called in both cases. Don't mix two different languages.
If you really need to call the destructors in the child, throw an exception and catch it in main. That will unwind the stack correctly.
Exit command should be avoid to use in any case except from ending the execution of the programme. For anything else, I would use return.

Running two programs concurrently

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.

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.

notify thread about changes in variable (signals?)

I have main() and thread in the same program.
there is a variable named "status", that can get several values
I need that when the variable changes, to notify the thread (the thread cnat wait for the status variable, it is already doing fluent task) .
is there an easy way to do so? similar to interrupts? how about signals?
the function inside the main:
int main()
{
char *status;
...
...
while (1)
{
switch (status)
{
case: status1 ...notify the thread
case: status2 ...notify the thread
case: status3 ...notify the thread
}
}
}
if someone could give me an example it will be great!
thanks!
Since you're already using the pthread library you can use conditional variables to tell the thread that there is data ready for processing. Take a look at this StackOverflow question for more information.
I understand that you do not want to wait indefinitely for this notification, however C++ only implements cooperative scheduling. You cannot just pause a thread, fiddle with its memory, and resume it.
Therefore, the first thing you have to understand is that the thread which has to process the signal/action you want to send must be willing to do so; which in other words means must explicitly check for the signal at some point.
There are multiple ways for a thread to check for a signal:
condition variable: they require waiting for the signal (which might be undesirable) but that wait can be bounded by a duration
action queue (aka channel): you create a queue of signals/actions and every so often the target thread checks for something to do; if there is nothing it just goes on doing whatever it has to do, if there is something you have to decide whether it should do everything or only process the N firsts. Beware of overflowing the queue.
just check the status variable directly every so often, it does not tell you how many times it changed (unless it keeps an history: but then we are back to the queue), but it allows you to amend your ways.
Given your requirements, I would think that the queue is probably the best idea among those three.
Might be this example helpful for you.
DWORD sampleThread( LPVOID argument );
int main()
{
bool defValue = false;
bool* status = &defValue;
CreateThread(NULL, 0, sampleThread, status, 0,NULL);
while(1)
{
//.............
defValue = true; //trigger thread
// ...
}
return 0;
}
DWORD sampleThread( LPVOID argument )
{
bool* syncPtr = reinterpret_cast<bool*>(argument);
while (1)
{
if (false == *syncPtr)
{
// do something
}
else (true = *syncPtr)
{
//do somthing else
}
}
}

Checking the status of a child process in C++

I have a program that uses fork() to create a child process. I have seen various examples that use wait() to wait for the child process to end before closing, but I am wondering what I can do to simply check if the file process is still running.
I basically have an infinite loop and I want to do something like:
if(child process has ended) break;
How could I go about doing this?
Use waitpid() with the WNOHANG option.
int status;
pid_t result = waitpid(ChildPID, &status, WNOHANG);
if (result == 0) {
// Child still alive
} else if (result == -1) {
// Error
} else {
// Child exited
}
You don't need to wait for a child until you get the SIGCHLD signal. If you've gotten that signal, you can call wait and see if it's the child process you're looking for. If you haven't gotten the signal, the child is still running.
Obviously, if you need to do nothing unitl the child finishes, just call wait.
EDIT: If you just want to know if the child process stopped running, then the other answers are probably better. Mine is more to do with synchronizing when a process could do several computations, without necessarily terminating.
If you have some object representing the child computation, add a method such as bool isFinished() which would return true if the child has finished. Have a private bool member in the object that represents whether the operation has finished. Finally, have another method private setFinished(bool) on the same object that your child process calls when it finishes its computation.
Now the most important thing is mutex locks. Make sure you have a per-object mutex that you lock every time you try to access any members, including inside the bool isFinished() and setFinished(bool) methods.
EDIT2: (some OO clarifications)
Since I was asked to explain how this could be done with OO, I'll give a few suggestions, although it heavily depends on the overall problem, so take this with a mound of salt. Having most of the program written in C style, with one object floating around is inconsistent.
As a simple example you could have a class called ChildComputation
class ChildComputation {
public:
//constructor
ChildComputation(/*some params to differentiate each child's computation*/) :
// populate internal members here {
}
~ChildComputation();
public:
bool isFinished() {
m_isFinished; // no need to lock mutex here, since we are not modifying data
}
void doComputation() {
// put code here for your child to execute
this->setFinished(true);
}
private:
void setFinished(bool finished) {
m_mutex.lock();
m_isFinished = finished;
m_mutex.unlock();
}
private:
// class members
mutex m_mutexLock; // replace mutex with whatever mutex you are working with
bool m_isFinished;
// other stuff needed for computation
}
Now in your main program, where you fork:
ChildComputation* myChild = new ChildComputation(/*params*/);
ChildPID= fork();
if (ChildPID == 0) {
// will do the computation and automatically set its finish flag.
myChild->doComputation();
}
else {
while (1) { // your infinite loop in the parent
// ...
// check if child completed its computation
if (myChild->isFinished()) {
break;
}
}
// at the end, make sure the child is no runnning, and dispose of the object
// when you don't need it.
wait(ChildPID);
delete myChild;
}
Hope that makes sense.
To reiterate, what I have written above is an ugly amalgamation of C and C++ (not in terms of syntax, but style/design), and is just there to give you a glimpse of synchronization with OO, in your context.
I'm posting the same answer here i posted at as this question How to check if a process is running in C++? as this is basically a duplicate. Only difference is the use case of the function.
Use kill(pid, sig) but check for the errno status. If you're running as a different user and you have no access to the process it will fail with EPERM but the process is still alive. You should be checking for ESRCH which means No such process.
If you're running a child process kill will succeed until waitpid is called that forces the clean up of any defunct processes as well.
Here's a function that returns true whether the process is still running and handles cleans up defunct processes as well.
bool IsProcessAlive(int ProcessId)
{
// Wait for child process, this should clean up defunct processes
waitpid(ProcessId, nullptr, WNOHANG);
// kill failed let's see why..
if (kill(ProcessId, 0) == -1)
{
// First of all kill may fail with EPERM if we run as a different user and we have no access, so let's make sure the errno is ESRCH (Process not found!)
if (errno != ESRCH)
{
return true;
}
return false;
}
// If kill didn't fail the process is still running
return true;
}