If not, how can we start a background process in C?
In Unix, exec() is only part of the story.
exec() is used to start a new binary within the current process. That means that the binary that is currently running in the current process will no longer be running.
So, before you call exec(), you want to call fork() to create a new process so your current binary can continue running.
Normally, to have the current binary wait for the new process to exit, you call one of the wait*() family. That function will put the current process to sleep until the process you are waiting is done.
So in order to create a "background" process, your current process should just skip the call to wait.
Use the fork() call to create a new process, then exec() to load a program into that process. See the man pages (man 2 fork, man 2 exec) for more information, too.
Fork returns the PID of the child, so the common idiom is:
if(fork() == 0)
// I'm the child
exec(...)
Related
I've done a fork and and then an exec but I don't know how to start it in the background.
Should I use an argument after the exec? If so, which is it?
If you simply want to background a process use daemon().
If you want to spawn off a process that then backgrounds itself 1st use fork() and inside this 1st child call fork() again letting the 2nd child call exec*() for the process to be backgrounded. Let the initial parent wait() for the 1st child.
As the parent of the second child (the process fork()ed 1st) dies, the exec*()ed process will be reaped by init.
Note: The pattern above is sometimes referred to as "double-forking". See also here: Why fork() twice (and links from there)
Another interesting set of answers on this is here: Linux: Difference between forking twice and daemon(ise)
I am having a little trouble with understanding execution flow of fork(). My main question is that when fork() is called does the calling process pause execution flow, or continue execution? Here is an example of what I'm working on
for (i = 0; i < hosts; i++)
{
if (fork() == 0)
{
forward_data(client_sock, remote_sock[i]);
}
}
Here I use the fork() function to create separate processes that handle connections between remote hosts. The function forward_data() sends data from client_sock to remote_sock, and I am designing the program to send to multiple hosts at the same time.
fork() will duplicate the process and both processes (original and clone) will continue to execute from there, the only difference is that in the parent process, fork() will return the PID of the new process that was created (or -1 if error), while in the child process fork() will have returned 0.
It doesn't quite count as multithreading as once this split happens, the processes are no longer in the same virtual memory space.
First, as noted elsewhere, fork() makes a copy of the current process, and then both the new and the old process continue after the fork() returns -- the new process will see fork() return 0, the old process will see fork() return the pid of the new (child) process.
In what you've written, the original process will spawn hosts children, and each child will run forward_data(). If forward_data() returns, then each child will then spawn hosts - 1 grandchildren, who will in turn each spawn hosts - 2 further greatgrandchildren and so on.
Second, the short answer to the question "does the calling process pause execution flow, or continue execution?" is yes. The longer answer is that the calling process may or may not execute at the same time as the newly created process, you cannot tell and it may be different every time -- if you care, then you need to use some IPC mechanism to synchronise as required.
Third, since the question is tagged "multithreading", if the old process is running more than one pthread, then the new process inherits all the mutexes, conditions etc of the old process, in the state they were in when fork() was called. However, the new process has only one pthread, and that is a copy of the pthread in the old process which executed the fork().
I am looking for C code to use on a Linux based system to start another process asynchronously. The second process should continue, even if the first ends. I've looked through the "fork" and "system" and "exec" options, but don't see anything that will spawn a peer process that's not communicating with or a child of the original process.
Can this be done?
Certainly you can. In the parent fork() a child, and in that child first call daemon() (which is an easy way to avoid setsid etc.), then call something from the exec family.
In Linux (and Unix), every process is created by an existing process. You may be able to create a process using fork and then, kill the parent process. This way, the child will be an orphan but still, it gets adopted by init. If you want to create a process that is not inherited by another, I am afraid that may not be possible.
You do a fork (man 2 fork) followed by an execl (man 2 execl)
For creates a new process of the same image as the calling process (so a perfect twin), where execl replaces one of the twins with a new image.
If you search google for "fork execl" you will find many text book examples -- including how to use correctly fork() and exec()
The most common fork-execl you will still have the new process associated to the terminal -- to create a perfect background process you need to create what is called a daemon process -- the template for that can be fornd in this answer here Creating a daemon in Linux
I want to write a 'zombie creator' and 'zombie terminator'. Main point is that I want to create zombies in one part and terminate them in other part of code. I'm using C.
Example:
create_zombie(); //let's say it's a spawn, using fork etc.
/* a houndred lines below */
kill_zombie(PID); // PID is determinated by user, I want to leave him the choice
I know how to do this using fork(), if .. else, but that's not the point. I'm looking for some kind of remote control. Is that possible? Sleeping him for a long time could be a solution?
I'm assuming Linux, but the process should be similar on other operating systems. You want to look into the kill() function declared typically declared in the signal.h header file. This will allow you to send a signal to a specific PID from your zombie killer. The easiest approach would be to send your zombie process a kill signal (SIGKILL). SIGKILL cannot be caught or ignored, and immediately kill a process dead.
If you need to do some cleanup in your zombie process, you can create a signal handler with the signal() function. This will allow you to specify a function to call when a process receives a signal. This function would implement your cleanup code and then exit().
On linux, your shell should have a kill command that mimics the functionality of kill(). The syntax is typically kill -s 9 PID. This will send a SIGKILL (signal number 9) to the process PID.
I hope this answer nudges you in the proper direction.
When you fork a process, fork returns 0 in the child process and the child's process id in the parent. You can save them in an array, write them to a file, or write them to a pipe and don't "uncap" the other end until you need it.
Heres a breakdown of my code.
I have a program that forks a child (and registers the child's pid in a file) and then does its own thing. The child becomes any program the programmer has dignified with argv. When the child is finished executing, it sends a signal (using SIGUSR1) back to the parent processes so the parent knows to remove the child from the file. The parent should stop a second, acknowledge the deleted entry by updating its table, and continue where it left off.
pid = fork();
switch(pid){
case -1:{
exit(1);
}
case 0 :{
(*table[numP-1]).pid = getpid(); //Global that stores pids
add(); //saves table into a text file
freeT(table); //Frees table
execv(argv[3], &argv[4]); //Executes new program with argv
printf("finished execution\n");
del(getpid()); //Erases pid from file
refreshReq(); //Sends SIGUSR1 to parent
return 0;
}
default:{
... //Does its own thing
}
}
The problem is that the after execv successfully starts and finishes (A printf statement before the return 0 lets me know), I do not see the rest of the commands in the switch statement being executed. I am wondering if the execv has like a ^C command in it which kills the child when it finishes and thus never finishes the rest of the commands. I looked into the man pages but did not find anything useful on the subject.
Thanks!
execv replaces the currently executing program with a different one. It doesn't restore the old program once that new program is done, hence it's documented "on success, execv does not return".
So, you should see your message "finished execution" if and only if execv fails.
execv replaces the current process with a new one. In order to spawn a new process, you can use e.g. system(), popen(), or a combination of fork() and exec()
Other people have already explained what execv and similar functions do, and why the next line of code is never executed. The logical next question is, so how should the parent detect that the child is done?
In the simple cases where the parent should do absolutely nothing while the child is running, just use system instead of fork and exec.
Or if the parent will do something else before the child exits, these are the key points:
When the child exits, the parent will get SIGCHLD. The default handler for SIGCHLD is ignore. If you want to catch that signal, install a handler before calling fork.
After a child has exited, the parent should call waitpid to clean up the child and find out what its exit status was.
The parent can also call wait or waitpid in a blocking mode to wait until a child exits.
The parent can also call waitpid in a non-blocking mode to find out whether the child has exited yet.
What did you expect to happen? This is what execv does. Please read the documentation which says:
The exec() family of functions replaces the current process image with a new process image.
Perhaps you were after system or something, to ask the environment to spawn a new process in addition to the current one. Or.. isn't that what you already achieved through fork? It's hard to see what you want to accomplish here.