I am writing a C program in Ubuntu 10 to create processes, display process ID and to kill process. I'm using kill() command to kill a process ID that user entered via scanf. However, the scanf is not working at all. I tried to add "space" before %d but nothing happened. Appreciate if anyone can help!
Following are my codes:
include <stdio.h>
include <unistd.h>
include <signal.h>
include <sys/types.h>
include <stdlib.h>
main ()
{
int x;
int pid[10]; // to store fork return value
int p[10]; // to store process ID
// Create 5 new processes and store its process ID
for (x=1;x<=5;x++)
{
if ((pid[x]=fork())==0)
{
p[x]=getpid();
printf("\n I am process: %d, my process ID: %d\n",x,p[x]); // Display process number and PID
}
else
exit(0);
}
{
int y;
y=p[x];
printf("Please enter a process ID to kill: ");
scanf(" %d", &y); //waiting for user input
printf("\nThe process %d is killed.\n",y);
kill(y,9); //Values 9 represents SIGKILL
}
}
Your parent process exits, and so does every process you spawn afterwards (their return value of fork is different than 1 so they exit). If a process has no parent it becomes an "orphan" and has special handling by the OS (some other process adopts it). Are you sure this is the behavior you were looking for?
EDIT:
This is probably what you meant to write:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
int main ()
{
int x;
int pid[10]; // to store fork return value
pid_t parent = getpid();
// Create 5 new processes and store its process ID
for (x=1;x<=5;x++)
{
if ((pid[x]=fork())!=0)
{
printf("\n I spawned process: %d, its process ID: %d\n",x,pid[x]); // Display process number and PID
}else{
while(1){}
}
}
if(getpid() == parent){
int y;
y=pid[x];
printf("Please enter a process ID to kill: ");
scanf(" %d", &y); //waiting for user input
printf("\nThe process %d is killed.\n",y);
kill(y,9); //Values 9 represents SIGKILL
}else{
printf("THIS SHOULD NOT HAPPEN!");
}
return 0;
}
fork returns twice, each time in a different process. One very important thing to realize about the two processes is that they do not share memory. That means that by calling getpid in the child and saving that in an array you are unable to see that value in the parent's copy of the variable.
What you most likely want to do is something like:
for (...) {
if ((pid[x]=fork()) == 0) {
printf("child created, pid = %d\n", getpid());
while(1) sleep(1000); /* children will never run outside this loop */
} else {
continue;
}
}
/* this code only runs in the parent */
Related
I'm trying to write a C program in which the main process creates two children: Ping and Pong. Ping prints “ping” followed by a number, and Pong prints “pong” followed by a number, the output must be as the sample run in Figure 1:"
Here is what I tried to do:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
void main(){
//initializing pipes
int td[2];
int td2[2];
pipe(td);
pipe(td2);
int pid=fork();
if(pid){ //in parent process
int pid2=fork();
if(pid2){// still in parent process
//1st time
int number1;
printf("Enter a number: ");
scanf("%d",&number1);
write(td[1],&number1,sizeof(number1));
printf("<>");
write(td2[1],&number1,sizeof(number1));
printf("--");
//2nd time
int number2;
printf("Enter a number: ");
scanf("%d",&number2);
write(td[1],&number2,sizeof(number2));
printf("<>");
write(td2[1],&number2,sizeof(number2));
printf("--");
}
else{// in pong process
int number;
read(td2[0],&number,sizeof(number));
printf("pong%d \n",number);
}
}
else{ //in ping process
int number;
read(td[0],&number,sizeof(number));
printf("ping%d \n",number);
}
}//main end
explanation: the problem that I faced here, is that the pong gets printed before ping and the parent process doesn't wait for its children to end ( and some output gets printed after root/desktop etc..)
Another problem that I solved, I had read method in the parent process, it fixed my problem because I know that read forces the program to wait until something is written to the pipe, but in this case, we have "write" in the parent process, so the parent is not waiting
I also tried to implementing wait(NULL) but it doesn't seem to work.
any suggestion would be much appreciated
It appears that you (your instructor) are over-complicating.
So, you want your main() to do
int main(void) {
int n;
//set up pipes and forks
printf("Enter a number"); scanf("%d", &n);
// make child1 output " ping<n>\n"
puts(" <>");
// make child2 output " pong<n>\n"
printf(" --\nEnter a second number"); scanf("%d", &n);
// make child1 output " ping<n>\n"
puts(" <>");
// make child2 output " pong<n>\n"
puts(" -- THE END --");
// close pipes
return 0;
}
So, except for "ping" vs "pong" (and using different pipes) the children are absolutely identical. Maybe we can send the string with the number and keep the number of functions down? No ... what about setting the string when creating the process? This sounds better
// set up pipes and forks
int pipes1[2], pipes2[2];
pipe(pipes1);
if (fork() == 0) /* child #1 */ child("ping", pipes1);
close(pipes1[0]); // the read end of the pipe belongs to the child
pipe(pipes2);
if (fork() == 0) /* child #2 */ child("pong", pipes2);
close(pipes2[0]); // we are not using the read end of the pipe
Now... how do we make a child (children are waiting at their read() call) work? Well, easy! We write on our end of the pipe
scanf("%d", &n); // get value from user
write(pipes1[1], &n, sizeof n); // automatically unblock child1
write(pipes2[1], &n, sizeof n); // automatically unblock child2
Repeat these statements for the 2nd user input.
Don't forget to close the write ends of the pipes
close(pipes1[1]);
close(pipes2[1]);
And that's the main() function. What about the function for the children? The child(char *sign, int pipes[2])?
void child(char *sign, int pipes[2]) {
close(pipes[1]); // close write end
int i;
for (;;) {
if (read(pipes[0], &i, sizeof i)) {
printf(" %s%d\n", sign, i); // print and go back to waiting at the read()
} else {
break; // exit the loop when read fails
}
}
close(pipes[0]); // no more reading
exit(EXIT_SUCCESS); // not going back to main()
}
I've written a C program that creates a child thread. After creating the child thread, the parent thread should output two messages. The first being "I am the parent" and the second "The parent is done". The same should occur for the child thread "I am the child" and "The child is done". However I want to make sure, the second message of the child is always done before the second message of the parent. How can I achieve this in my code below?
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
int status = 0;
void *print_child(void *arg)
{
while (status == 0)
{
printf("Signal hasn't changed..\n");
sleep(1);
}
printf("The child has started...\n");
printf("The child is done! \n ");
}
int main()
{
pthread_t child;
pthread_create(&child, NULL, &print_child, NULL);
sleep(2);
printf("The parent has started...\n");
printf("The parent is done! \n");
status++;
if (pthread_join(child, NULL))
{
printf("ERROR");
exit(1);
}
}
Once a thread created it process independently and act like a separate process from the main thread. In your case you are joining the child thread after the statement printf("The parent is done! \n");. It not necessary that operating system will complete the child thread first always. Hence your expected result might not meet always. put a long sleep statement just before statement printf("The parent is done! \n"); and check but still not necessary that child will complete first.
The reason your code doesn't work is because you aren't making sure that the second printf in the parent thread is being executed before the second printf in the child thread.
A good option in this case would be to use mutexes. In this case, you can use a mutex to act as a 'guard' before the second printf, so the code will look something like this:
pthread_mutex_t print_lock;
...
In print_child:
// can only acquire after the parent releases, therefore guaranteeing that
// the parent thread has already printed the second statement
pthread_mutex_lock(&print_lock);
printf("The child is done! \n ");
pthread_mutex_unlock(&print_lock);
In main:
// lock it before the child thread is
// started, therefore guaranteeing the parent will have initial ownership
pthread_mutex_lock(&print_lock);
pthread_create(&child, NULL, &print_child, NULL);
sleep(2);
printf("The parent has started...\n");
printf("The parent is done! \n");
pthread_mutex_unlock(&print_lock);
...
Just put following line after printf("The parent has started...\n"); and before printf("The parent is done! \n");:
status++;
if (pthread_join(child, NULL))
{
printf("ERROR");
exit(1);
}
So corrected code will be as following:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
int status = 0;
void *print_child(void *arg)
{
while (status == 0)
{
printf("Signal hasn't changed..\n");
sleep(1);
}
printf("The child has started...\n");
printf("The child is done! \n ");
}
int main()
{
pthread_t child;
pthread_create(&child, NULL, &print_child, NULL);
sleep(2);
printf("The parent has started...\n");
status++;
if (pthread_join(child, NULL))
{
printf("ERROR");
exit(1);
}
printf("The parent is done! \n");
return 0;
}
I am executing a really simple program which takes input in integer from user using scanf. I execute this program as a child program via fork() and execv.The child program never takes input from user.Any help would be appreciated.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
pid_t childpid;
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
execv("child",NULL);
exit(1);
}
else
{
printf("Parent process is terminating...\n");
return 0;
}
}
and the child code is
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int temp;
printf("This is Child Process. Child is going to sleep for 5 seconds\n");
sleep(5);
printf("Please enter an integer to terminate the process ");
scanf("%d",&temp);
printf("You entered %d ",temp);
printf("Child terminated");
return 0;
}
OUTPUT
[#localhost cascading]$ ./cascading
Parent process is terminating...
[#localhost cascading]$ This is Child Process. Child is going to sleep for 5 seconds
Please enter an integer to terminate the process You entered 12435[#localhost cascading]$ ^C
[#localhost cascading]$
I am running the code in fedora installed on a virtual machine.Thanks
Once the parent process finishes, control is returned to shell; and stdin could be closed.
To retain child's access to stdin, you can let the parent wait until the child is done.
So, in your parent:
else {
printf("Parent process is terminating...\n");
wait(NULL);
return 0;
}
You need to wait for child process to be finished, please modify your code like this
if(childpid == 0)
{
execv("child",NULL);
exit(1);
}
else
{
wait(); //wait for child
printf("Parent process is terminating...\n");
return 0;
}
If I run this program will I have defunct processes? I am trying to create a main program that runs 5 process in parallell and then not getting defunct processes. The trouble is mostly to be sure that this is not happening. Im not quite sure if Im doing it right this far. I have heard that it is good practice to make sure you dont have defunct processes by making your process "wait()" for as many children that has been "fork()"ed.
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
void forkChildren(int nrofChildren, int *nr_of_children) {
pid_t pid;
int i;
for(i=0; i<5; i++) {
/* fork a child process */
pid = fork();
(*nr_of_children)++;
/* error occurred */
if (pid < 0) {
fprintf(stderr, "Fork failed\n");
exit(-1);
}
/* successful child */
else if (pid == 0) {
int sleeptime=1; //rand()%10;
printf("I am child: %d \nwith parent: %d \nin loop: %d \nand will sleep for: %d sec\n\n", getpid(), getppid(), i, sleeptime);
sleep(sleeptime);
printf("Ending of child: %d \nwith parent :%d in loop: %d\n\n", getpid(), getppid(), i);
}
/* parent process
else {
wait(NULL); Do I need this to make sure I dont get defunct processes???
} */
}
}
int main(int argc, char *argv[]) {
srand((unsigned int)time(NULL));
int nr_of_children=0;
if (argc < 2) {
/* if no argument run 5 childprocesses */
forkChildren(5, &nr_of_children);
} else {
forkChildren(atoi (argv[1]), &nr_of_children);
}
wait(NULL);
printf("End of %d, with %d nr of child-processes\n\n", getpid(), nr_of_children);
return 0;
}
Yes, you need to wait on the child processes. The reason is that otherwise there will still be data associated with the now zombie process, for example space for the process return value.
Have a look at using the daemon() command to place your app in the background, then use pthreads to manage the parallelism.
NAME
daemon - run in the background
SYNOPSIS
#include
int daemon(int nochdir, int noclose);
Feature Test Macro Requirements for glibc (see
feature_test_macros(7)):
daemon(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
DESCRIPTION
The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as
system daemons.
If nochdir is zero, daemon() changes the process’s current working directory to the root directory ("/"); otherwise,
If noclose is zero, daemon() redirects standard input, standard output and standard error to /dev/null; otherwise, no changes are made
to these file descriptors.
So I'm getting into Concurrent Programming, but for some reason I can't even get the basics to work. I have a file called fork.c, which contains a method main. In this method main I fork twice, into child processes 1 and 2.
In child 1, I print the character 'A' 50 times.
In child 2, I print the character 'B' 50 times.
When I run my code, I get the output AAAAA...AAAABBBBBB....BBBBBB. But never something like ABABABABABABAB.... In fact, sometimes I even get BBBBB....BBBBAAAA....AAAAA.
So why am I experiencing this behavior? Perhaps I'm going about it completely wrong.
#include <stdlib.h>
#include <stdio.h>
void my_char(char n) {
write(1, &n, 1);
}
int main() {
int status;
pid_t child1, child2;
if (!(child1 = fork())) {
// first childi
int a;
for (a = 0; a < 50; a++) {
my_char('A');
}
exit(0);
} else if (!(child2 = fork())) {
// second child
int a;
for (a = 0; a < 50; a++) {
my_char('B');
}
exit(0);
} else {
// parent
wait(&child1);
wait(&child2);
my_char('\n');
}
return 0;
}
They are running concurrently, but the processes end almost immediately after being started. In other words, they're too short to actually get any real overlap.
EDIT:
The time needed to start another process is longer than the time it takes to run them. Therefore the chance of overlap is small. (there are also buffering issues which I'll omit)
You need each process to do more work than that. Try printing more than 50. Printing more than 10000 will probably be enough.
I think this is much easier to figure how fork() works:
#include <stdlib.h>
#include <stdio.h>
int main() {
pid_t child1, child2;
printf("Start\n");
if (!(child1 = fork())) {
// first childi
printf("\tChild 1\n");
sleep(5);
exit(0);
} else if (!(child2 = fork())) {
// second child
printf("\tChild 2\n");
sleep(5);
exit(0);
} else {
// parent
printf("Parent\n");
wait(&child1);
printf("got exit status from child 1\n");
wait(&child2);
printf("got exit status from child 2\n");
}
return 0;
}
...and here is the output:
Start
Child 1
Parent
Child 2
got exit status from child 1
got exit status from child 1