I use fork() in order to make different proccesses running and printing a simple message.The result of the code counfuses me though.. Take a look at the code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <time.h>
int main(void)
{
fork();
fork();
fork();
fprintf(stderr,"hello world\n");
}
and the output is:
mario#ubuntu:~/OS$ ./main
hello world
hello world
hello world
hello world
hello world
hello world
mario#ubuntu:~/OS$ hello world
hello world
mario#ubuntu:~/OS$
Note that i execute the program at the first line of the terminal but the output is not what i expected. Please help me! Thanks in advance! Same things happen if fprintf is changed with printf("......")
EDIT:I cant understand why the prints are this way. Six before the terminal line one next to it and 1 after it...
When the parent program exited, the shell running the parent program printed the shell prompt mario#ubuntu:~/OS$ on the screen. Any child program which had not printed it's hello world by then would be printed after the prompt. If you want the prompt to not appear before all the hello worlds, you need to make the parent wait for all it's child and grandchild programs to terminate.
Check this to see how to make parent wait.
You are creating 8 processes. Each fork divides the process into two. It the original parent finishes the other processes my still be executing. Hence if the original process finishes executing the shell gets a go and prints the prompt despite the other processes are still executing.
Related
I have a C program. I noticed that you can't put 2 execl's in it.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t fork(void);
int system(const char *command);
execl("/bin/sh", "sh", "-c", "kdialog --warningcontinuecancel
\"Make sure to include: \n \n 1. py_lcd folder \n 2. 4x20
Raspberry Pi LCD Display \n 3. Python 2.7.12 to be installed \n
\n If you are missing something, kill the program process and
get them.\"", (char *) 0);
sleep(1);
execl("/bin/sh", "sh", "-c", "kdialog --msgbox \"Setting up files...\" --title \"Installing...\"", (char *) 0);
return(0);
}
Can someone help me if there is a way to bypass this or if i am making a mistake???
The exec family of functions don't return when they succeed. They replace the running process with the one being execed. If you want to run a program in a child process (with full control, unlike system), you need to use fork + exec + wait (or perhaps posix_spawn).
Anything written after execl is a deadcode. The main purpose of execl is to re-use the current process information for a new process to improve performance. You will be using sharing the same structures of process information(pid, stack, heap etc.) of the current process where execl is executed.
I found an answer myself. There is a system() command which works the exact same but you are able to insert it anywhere in the code without problems
I am looking for a ptrace() call to observe a process until the process exits.
I have this which compiles with gcc / cc on OSX:
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sys/ptrace.h>
int main(int argc, char *argv[]) {
pid_t pidx = atoi(argv[1]);
printf("pid = %jd\n", (intmax_t) pidx);
ptrace(PT_ATTACHEXC, pidx, 0, 0);
wait(NULL);
}
However, even with a valid/existing pid, this program will still exit immediately. I am trying to only exit this program after pidx dies.
Is this possible somehow?
Ideally I want something that works on both OSX and Linux.
Your problem is probably that the wait call returns immediately, because the traced "inferior" process is suspended, you know, waiting for you to debug it. You're going to need some kind of loop in which you make ptrace requests to inspect the child and then resume execution, and then call wait again to wait for it to suspend on the next breakpoint or whatever. Unfortunately the debugger API is extremely non-portable; you will have to write most of this program twice, once for OSX and once for Linux.
This is my code. I'm completely aware that an endless loop results when executing directly. What I did was I compiled this code and then executed twice in the linux command line via ./a.out & twice. The first time the program executes, it runs fine and gives a decent file handle. When the first instance of the program is running in the background and I execute the second instance one minute later (via ./a.out &), the file handle returned is the exact same. I was expecting a negative return value for the second instance to indicate the first instance is using the file.
How do I solve this issue? I don't want to use buffered file functions like fopen/fread because the file I want to make is small and must be made at the beginning of the program before anything else happens in the code.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
char* pidf="/testpid.del";
int lfp=open(pidf,O_WRONLY|O_CREAT|0x700);
printf("File handle = %d\n",lfp);
if (lfp ==-1){printf("Can't use PID file: %s\n",pidf);return -1;}
while(1){
sleep(1);
}
close(lfp);
}
In this program, I am trying to use fork() functions to create 6 child processes and execute executionnode() functions,but I feel there is something wrong in my output!
what happened to my code or system calls?
I have a program like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
int executionnode(int i);
int main(){
pid_t childpid;
int i;
int row=6;
for(i=0;i<row;i++)
{ childpid=fork();
if(childpid==0)
continue;
else if (childpid>0)
executionnode(i);
else {
perror("something wrong");
exit(1);
}
}
}
int executionnode(int i){
sleep(i);
printf("hello, I am process:%ld\n",(long)getpid());
char *execArgs[] = { "echo", "Hello, World!", NULL };
execvp("echo", execArgs);
}
Everytime when I run this program,the output is always like this in my Linux terminal:
/*
hello, I am process:3226
Hello, World!
lixx3527#tiandiao123:~/Desktop/pa1-release$ hello, I am process:3227
Hello, World!
hello, I am process:3228
Hello, World!
hello, I am process:3229
Hello, World!
hello, I am process:3230
Hello, World!
hello, I am process:3231
Hello, World!
*/
I find my output even didn't finish, which means my program's executions haven't been finished, but lixx3527#tiandiao123:~/Desktop/pa1-release$ has appeared in the terminal ahead of time.
what happened to my code or system calls?
can someone help me explain it? I mean why lixx3527#tiandiao123:~/Desktop/pa1-release$ appeared before the program finished its all the execution?
thank you!
The parent runs very quickly, forking children. Then it quits and the shell prints a prompt. Then the other children run and print data. It looks like one child is able to print before the shell prints a prompt, and the others don't. If you want the parent to wait for the children to finish, there is a function conveniently named wait that will do that.
This question already has answers here:
printf anomaly after "fork()"
(3 answers)
Closed 7 years ago.
I was writing a multi-process program using fork() and i bumped into a problem.
Below is a sample code reproducing the problem (without any sort of error checking):
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
printf("hello world");
fork();
}
This code prints 2 "hello world" statements (one from parent and the other from child). However this should not be the case since the printffunction call is prior to the fork() system call.
After testing, the problem appears to be solved by the following:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
printf("hello world\n"); \\ addition of the new line character
// or by using fflush(stdout);
fork();
}
My guessing is that the printf buffer is being copied while its not flushed, so the child process is emptying its copy of this buffer before exiting. Hence the other printf shows.
Can anyone provide a better explanation of this issue? Or even better, correct me if i am wrong or missing something.
The file handle stdout (which is used by printf) is by default line buffered, which means output using printf will be flushed (and shown in the console) either when there's a newline or when the buffer is full.
As fork creates an exact duplicate of the parent process, both processes have the same contents in the (un-flushed) output buffer, and both will be flushed when the two processes exits.
So yes you're correct in your guessing.