Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
How to execute/open/run another program from C, and not block on this but let it run simultaneously. Then I want to to do some test like server/client and then if this has been done I want to just kill/close this program. I have read about
system() or execv()
But first seems to be blocking an waiting for results, second seems to work only on Linux? In the best case scenario I would like to have cross-platform or minimum MacOS/Windows/Linux(Ubuntu) working solution. I also need to shutdown this previously opened program when I don't need it any more.
The POSIX way to do it (which maybe could be used in Windows too -- https://technet.microsoft.com/en-us/library/bb463220.aspx ?)
is to use a fork + exec* combo:
You use fork to create a new process that copies the current process.
Your handle to that process is an int process identifier (pid):
int pid;
if (0 > (pid=fork()){
perror("fork failed");
return -1;
}
if (0 == pid){
//CHILD PROCESS
printf("I'm the child process, my pid is: %d\n", getpid());
}
//pid > 0 ==> PARENT PROCESS
puts ("I'm the parent process");
printf("The pid of the child I've just spawned is %d\n", pid);
To run an executable in the child process, use an exec* function to replace the current (e.g., the child's if you run it in the child) process image with a process image loaded from an executable file.
In the parent, you can then use the pid handle to kill the process (=ask it to terminate):
kill(pid, SIGTERM); //please terminate
and you can use waitpid to retrieve its exit status after it has terminated .
( system internally uses fork + execv (it execs a shell) + waitpid. Because the waitpid part isn't separate in system, system makes you wait for the child process to finish.)
You'll probably also want to look into dup2 and pipe or socketpair to set up a fildescriptor-based communication channel with the child process (there are other options such as shared memory, message queues, or signals if you only need very basic communication).
The manpages are a good resource on managing processes and IPC.
How to execute/open/run another program from C ?:
use system
How not to block on it?
you have to implement multitasking, so use fork to create another processes or pthread_create
to create another thread, take a look at this
I would like to have cross-platform or minimum macOS/Windows/Linux(Ubuntu) working solution.
system works on linux and windows but i don't have any ideas about the other platforms
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
What if I'm writing this??
I got both of the printf statements executed!!
#include<stdio.h>
#include<stdlib.h>
int main(void){
if(fork())
printf("entering IF");
else
printf("entering ELSE");
return 0;
}
What exactly are you asking?
fork() duplicates the calling process, returning the child process' PID in the parent, and 0 in the child.
In C, if evaluates any non-zero value to true, meaning entering IF will be printed from the parent thread, and entering ELSE from the child thread.
It should be noted that order in which they are printed is nondeterministic, so you may see entering ELSE before entering IF.
See: man(2) fork
The fork system call return value as per manual pages is
Return Value
On success, the PID of the child process is returned in the parent, and 0 is
returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
So, the if statement is executed by the parent process and where as the else is executed by the child process.
The fork() creates a child process by duplicating the calling process. The process that invokes fork() is the parent process and the newly created process is the child process. So fork() splits a process in two, and returns 0 to the child process and the PID of the child process to the parent process, or -1 if the fork failed.
In the context of your program:
if(fork())
printf("entering IF");
else
printf("entering ELSE");
the parent process will print entering IF and child process will print entering ELSE.
The child process and the parent process run separately. So, you cannot determine which process gets schedules first but there are ways to synchronize them. For e.g. make parent process wait until child finishes, check this.
Additional:
Linux kernel (2.6.23 and later) provides a tunable paramter - sched_child_runs_first.
From this:
/proc/sys/kernel/sched_child_runs_first (since Linux 2.6.23)
If this file contains the value zero, then, after a fork(2),
the parent is first scheduled on the CPU. If the file con‐
tains a nonzero value, then the child is scheduled first on
the CPU. (Of course, on a multiprocessor system, the parent
and the child might both immediately be scheduled on a CPU.)
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().
This question already has answers here:
What is the reason for performing a double fork when creating a daemon?
(9 answers)
Closed 8 years ago.
Nagios lets me configure child_processes_fork_twice=<0/1>.
The documentation says
This option determines whether or not Nagios will fork() child processes twice when it executes host and service checks. By default, Nagios fork()s twice. However, if the use_large_installation_tweaks option is enabled, it will only fork() once.
As far as I know fork() will spawn a new child process. Why would I want to do that twice?
All right, so now first of all: what is a zombie process? It's a process that is dead, but its parent was busy doing some other work, hence it could not collect the child's exit status. In some cases, the child runs for a very long time, the parent cannot wait for that long, and will continue with it's work (note that the parent doesn't die, but continues its remaining tasks but doesn't care about the child). In this way, a zombie process is created. Now let's get down to business. How does forking twice help here? The important thing to note is that the grandchild does the work which the parent process wants its child to do. Now the first time fork is called, the first child simply forks again and exits. This way, the parent doesn't have to wait for a long time to collect the child's exit status (since the child's only job is to create another child and exit). So, the first child doesn't become a zombie. As for the grandchild, its parent has already died. Hence the grandchild will be adopted by the init process, which always collects the exit status of all its child processes. So, now the parent doesn't have to wait for very long, and no zombie process will be created. There are other ways to avoid a zombie process; this is just a common technique. Hope this helps!
In Linux, a daemon is typically created by forking twice with the intermediate process exiting after forking the grandchild. This has the effect of orphaning the grandchild process. As a result, it becomes the responsibility of the OS to clean up after it if it terminates. The reason has to do with what are known as zombie processes which continue to live and consume resources after exiting because their parent, who'd normally be responsible for the cleaning up, has also died.
Also from the documentation,
Normally Nagios will fork() twice when it executes host and service checks. This is done to (1) ensure a high level of resistance against plugins that go awry and segfault and (2) make the OS deal with cleaning up the grandchild process once it exits.
Unix Programming Faq §1.6.2:
1.6.2 How do I prevent them from occuring?
You need to ensure that your parent process calls wait() (or
waitpid(), wait3(), etc.) for every child process that terminates;
or, on some systems, you can instruct the system that you are
uninterested in child exit states.
Another approach is to fork() twice, and have the immediate child
process exit straight away. This causes the grandchild process to be
orphaned, so the init process is responsible for cleaning it up. For
code to do this, see the function fork2() in the examples section.
To ignore child exit states, you need to do the following (check your
system's manpages to see if this works):
struct sigaction sa;
sa.sa_handler = SIG_IGN;
#ifdef SA_NOCLDWAIT
sa.sa_flags = SA_NOCLDWAIT;
#else
sa.sa_flags = 0;
#endif
sigemptyset(&sa.sa_mask);
sigaction(SIGCHLD, &sa, NULL);
If this is successful, then the wait() functions are prevented from
working; if any of them are called, they will wait until all child
processes have terminated, then return failure with errno == ECHILD.
The other technique is to catch the SIGCHLD signal, and have the
signal handler call waitpid() or wait3(). See the examples section
for a complete program.
This code demonstrates how to use the double fork method to allow the grandchild process to become adopted by init, without risk of zombie processes.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main()
{
pid_t p1 = fork();
if (p1 != 0)
{
printf("p1 process id is %d", getpid());
wait();
system("ps");
}
else
{
pid_t p2 = fork();
int pid = getpid();
if (p2 != 0)
{
printf("p2 process id is %d", pid);
}
else
{
printf("p3 process id is %d", pid);
}
exit(0);
}
}
The parent will fork the new child process, and then wait for it to finish. The child will fork a grandchild process, and then exit(0).
In this case, the grandchild doesn't do anything except exit(0), but could be made to do whatever you'd like the daemon process to do. The grandchild may live long and will be reclaimed by the init process, when it is complete.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
In Linux, how to prevent a background process from being stopped after closing SSH client
I have a C program which I access and interact with over terminal (usually from SSH on a linux box). I have been trying to find the solution to the problem where after I close the terminal/logout, the process ends with it (the program basically asks for some options then goes about its business with no further interaction required so I would like to have it continue to run even after I logout of SSH).
There are ways in linux to avoid this such as 'screen', but I want to do it programatically with C without relying on installed packages such as screen- even if this means reinventing the wheel.
So far I understand fork() to be the standard trivial way to daemonize a process, so could anyone help me to finish the code that allows the above described process to happen?
Within parent:
main()
{
//Do interactive stuff
signal(SIGCHLD, SIG_IGN); //stops the parent waiting for the child process to end
if(fork())
exit(0);
// and now the program continues in the child process
I can now logout of SSH which closes the original shell...and the child continues its work!
Within child:
//Continue with processing data/whatever the program does (no input/output to terminal required)
exit(0);
to detach the process from the parent:
use setsid() on the children process, it will run the program in new session
sid = setsid();
To Keep a program running even when the terminal is closed:
SIGHUP is a signal sent to a process when its controlling terminal is closed.
try to ignore it using
signal (SIGHUP, SIG_IGN);
I wrote a small server program. I wanted to see how it is handling multiple requests. So I wrote the following program to simulate multiple clients.
Pseudo Code:
main()
{
//set up all necessary data structures to connect to the server
fork();
fork();
fork();
create_socket();
connect()
//more code
}
Is there a better way of doing it? What tools I can use to test multi threaded program in C(at least the basic functionality)?
You've basically created a "process-fan" with this approach, so yes, that can work, although it's not threading ... you're actually creating new processes. Therefore you will want, in order to prevent zombie child processes, to "wait" for all processes to complete in each process that has spawned a new process. You could do this with the following line at or near the end of your main() for all processes that have called fork() (i.e., include the child-processes as well since they are spawning additional processes):
while(wait(NULL) != -1 || errno == EINTR);
This will wait for all the child-processes the current process has spawned, while preventing any early returns of wait() due to your process catching a signal. When there are no remaining child-processes for the current process, then wait() will return -1 and set errno to ECHILD, thus exiting the while-loop.