Is there a way to use system() and ask for the code to wait a few seconds?
I have been trying something like:
system("MyCmd");
sleep(8000);
However, sleep() terminates "MyCmd" execution.
Any thoughts?
However, sleep() terminates "MyCmd" execution.
No. The sleep() expression doesn't terminate the child process created with the system() call, the expressions
system("MyCmd");
sleep(8000);
will just be executed sequentially.
What you can do is to call fork() to create a child process, call sleep() in the parent process, and kill() the child process, if it's still running after the parent process awakes:
pid_t pid = fork();
if (pid == 0) {
// child process
execl ("/bin/MyCmd", "MyCmd", (char *)0);
}
else if (pid > 0) {
// parent process
sleep(8000);
kill(pid,SIGKILL);
}
else {
// fork failed
printf("fork() failed!\n");
return 1;
}
Related
I'm looking to implement a function similar to CreateProcess but on Linux. I did a lot of research and found the "Fork off and die" approach which uses a double fork to run the child under init. That is, allow the child to operate independent of the parent.
Because the parent needs to return information about the newly created child process (i.e. pid, name, etc.) I need to know if I'm running into a race condition in my code. Currently, I fork and retrieve the second fork's pid via pipes then wait for the first fork to exit.
int child = 0;
int fd[2] = { 0, 0 };
if (pipe (fd) != 0)
return Process();
int pid = fork();
if (pid < 0)
return Process();
if (pid == 0) // Child
{
if (setsid() != -1)
{
child = fork();
if (child == 0)
{
umask (0); // Reset umask
close (0); // Close stdin
close (1); // Close stdout
close (2); // Close stderr
execvp ( ... );
_exit (0);
}
// Do I need waitpid (child) here?
}
// Write the child PID using the pipe
write (fd[1], &child, sizeof (child));
_exit (0);
}
else // Parent
{
// Read the child PID using the pipe
read (fd[0], &child, sizeof (child));
// Remove zombie process
waitpid (pid, nullptr, 0);
// Child must finish exec by this point
return Process (child);
// Also gets name
}
Questions:
Do I need a second waitpid to wait for the child to finish the exec?
Does waitpid return upon a call to exec?
Does waitpid return even if exit or exec were called before waitpid?
You do not need to waitpid() on the second child. When a process's parent dies, the child will be adopted by the init process, so there will not be a zombie process.
waitpid() only returns after the child it waits on exits. A call to execvp() in the child means the waiter waits until the program that was executed dies, since that is when the child would die.
waitpid() will get the exit status of the process. It doesn't matter when the process actually exited.
(A little clarification: what you're calling child, is actually your grandchild. It's the child of the process that just forked off and died.)
Do I need a second waitpid to wait for the child to finish the exec?
You can't. It's your grandchild and you can only wait on your direct children. Additionally, because your grandchild's parent has died, your grandchild has now been reparented to init (so it's actually your ex-grandchild).
Does waitpid return upon a call to exec?
Waitpid returns when the given pid dies/exits or immediately if it's already a zombie. The exec is called in the grandchild. Your waitpid calls are not at all not concerned with processes that aren't your direct children (unless you're using the Linux-only child-subreaper feature).
Does waitpid return even if exit or exec were called before waitpid?
Waitpid only ever returns when the waited on pid (which must be your direct child) is dead. If that's not yet the case, it will block.
I wish to create a thread in a child process before the respective child process changes it's image using exec system call. However, seemingly, the pthread_create call is being overlooked.
pthread_t thread;
pthread_attr_t attribute;
pthread_attr_init(&attribute);
pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_DETACHED);
pid_t cid = fork();
if(cid == 0) //CHILD Process
{
switch(x->option)
{
case 1: pthread_create(&thread, &attribute, compressShow, NULL);
execl("/home/aamir/Lab/ass3/compression", "compression", source, destination, NULL);
cout<<"Execution failed."<<endl; break; //This segment will execute if exec fails.
}
else //PARENT Process
{
wait(0); //Prevents termination of original main until forked exec completes execution
pthread_cancel(thread);
}
The thread is basically just a progress display that is intended to output '.' (dots) in concurrence with the forked child.
If I remove the exec call the thread does execute. I've searched on google and read somewhere that you cannot use pthread_create between a fork and exec, something to do with async safe functions. Can you please help?
The exec bit zapps everything including threads and just starts a new process. That includes memory etc.
The program might (and usually) does not get to the bit to fire up the thread.
I have the following code fork()'s 2 children from a common parent and implements a pipeline between them. When I call the wait() function in the parent once only the program runs perfectly. However if I try to call the wait() function twice (to reap from both the children), the program does nothing and must be force exited.
Can someone tell me why I can't wait for both children here?
int main()
{
int status;
int pipeline[2];
pipe(pipeline);
pid_t pid_A, pid_B;
if( !(pid_A = fork()) )
{
dup2(pipeline[1], 1);
close(pipeline[0]);
close(pipeline[1]);
execl("/bin/ls", "ls", 0);
}
if( !(pid_B = fork()) )
{
dup2(pipeline[0], 0);
close(pipeline[0]);
close(pipeline[1]);
execl("/usr/bin/wc", "wc", 0);
}
wait(&status);
wait(&status);
}
You need to close both ends of the pipe in the parent after you fork the children. The problem is that output of ls is going to the parent, and the wc is waiting for input. So the first wait cleans up the ls, but the second is waiting for wc which is blocked on a pipe that's not receiving data.
Process B (wc) does not terminate until it receives end-of-file on its input stream. The other end of the pipe is shared as both the output stream of process A, and as pipeline[1] in the parent process, so you will need to close(pipeline[1]) in the parent process before waiting for process B.
When using the fork system call in C++, what is the easiest way to kill a child process if it takes too much time to execute what it is supposed to execute?
Like if somehow it gets into an infinite loop.. What should the parent process do to set the timeout for the child process?
Use WNOHANG with waitpid and sleep in between. Something like this should do it:
while (times < max_times) {
sleep(5); /* sleep 5 seconds */
rc = waitpid(-1, &status, WNOHANG);
if (rc < 0) {
perror("waitpid");
exit(1);
}
if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* it's done */
break;
}
times++;
}
if (times == max_times) {
/* ... */
}
I think you need waitpid with timeout and on timeout kill child process (assuming that child is hung). Check this page for ideas:
Waitpid equivalent with timeout?
I'm trying to execute an external program from inside my Linux C++ program.
I'm calling the method system("gedit") to launch an instance of the Gedit editor. However my problem is while the Gedit window is open, my C++ program waits for it to exit.
How can I call an external program without waiting for it to exit?
You will need to use fork and exec
int fork_rv = fork();
if (fork_rv == 0)
{
// we're in the child
execl("/path/to/gedit", "gedit", 0);
// in case execl fails
_exit(1);
}
else if (fork_rv == -1)
{
// error could not fork
}
You will also need to reap your child so as not to leave a zombie process.
void reap_child(int sig)
{
int status;
waitpid(-1, &status, WNOHANG);
}
int main()
{
signal(SIGCHLD, reap_child);
...
}
In regards to zombie processes, you have a second option. It uses a bit more resources (this flavor forks twice), but the benefit is you can keep your wait closer to your fork which is nicer in terms of maintenance.
int fork_rv = fork();
if (fork_rv == 0)
{
fork_rv = fork();
if (fork_rv == 0)
{
// we're in the child
execl("/path/to/gedit", "gedit", 0);
// if execl fails
_exit(1);
}
else if (fork_rv == -1)
{
// fork fails
_exit(2);
}
_exit(0);
}
else if (fork_rv != -1)
{
// parent wait for the child (which will exit quickly)
int status;
waitpid(fork_rv, &status, 0);
}
else if (fork_rv == -1)
{
// error could not fork
}
What this last flavor does is create a child, which in turns creates a grandchild and the grandchild is what exec's your gedit program. The child itself exits and the parent process can reap it right away. So an extra fork but you keep all the code in one place.
Oh, let me say it!
http://en.wikipedia.org/wiki/Fork-exec
Fork! :)
First, did you try to launch in background with system("gedit&")?
If that does not work, try spawning a new thread and running gedit from there.
I presume that you are not concerned with the result of the edit, or the contents of the edited file?