LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 08-03-2007, 08:06 AM   #1
expeliarmus
LQ Newbie
 
Registered: Jul 2007
Posts: 17

Rep: Reputation: 0
how can you pause child/parent processes in C and execute another function.


hi,
the program i have written so far,spawns child processes each of which perform some simple exponential calculations to generate load.I am able to increase loads easily by just spawning more and more child processes.what i am trying to do now is to pause these child processes by pressing a keystroke button and execute a function to kill these child processes.I tried taking ctrl+c as an input to pause child processes,put in a signal handler to ignore this signal's default function(which is termination),and execute a kill function on a dynamic array that contains pids of chilren processes,to terminate child processes.But immediately on pressing ctrl +c ,and entering a desired load, the entire program terminates.what do I do to pause child processes and execute a function to decrease load??

Last edited by expeliarmus; 08-03-2007 at 08:08 AM.
 
Old 08-03-2007, 08:16 AM   #2
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Quote:
immediately on pressing ctrl +c ,and entering a desired load, the entire program terminates.what do I do to pause child processes and execute a function to decrease load?
You fix the bug. There is no magic bullet.

Write a small, complete program which illustrates the problem. By "complete", I mean something that can compile right off the screen without the reader having to add any more #includes. By "small", I mean only complex enough to illustrate the problem, not your complete application.

Then post that code here. When you do, put it in CODE markers. To put it in CODE markers:
  1. Click the Go Advanced button at the bottom of the editing window.
  2. In the new editing window, highlight the code with your mouse.
  3. Click the # icon at the top of the editing window.
 
Old 08-03-2007, 09:58 AM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
You can't block a SIGKILL signal, which is what [Ctrl]+C will give you. You are thinking of SIGTERM. You can change what [Ctrl]+C does by setting the terminal properties, though. To stop the child processes, you will need to send a SIGSTOP signal to each one. You should also think about creating process groups to allow you to signal all processes in a group at one time.
ta0kira
 
Old 08-03-2007, 10:17 AM   #4
expeliarmus
LQ Newbie
 
Registered: Jul 2007
Posts: 17

Original Poster
Rep: Reputation: 0
the sample code

thank you guys.wjevans,here's a sample code.the program computes a number say n,raised n times.
Code:
#include<stdio.h> /*a program to find out p^p,ptimes,that is if the input is 2,output gives,2^2^2.if
                   input is 3,output is 3^3^3,and so on */
#include<stdlib.h>
#include<math.h>
#include<unistd.h>
#include  <sys/types.h>
#include  <signal.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>

/* ---------------------------------------------------------------- */
/*                 signal handler function prototypes               */
/* ---------------------------------------------------------------- */

void  SIGINT_handler(int);         /* for SIGINT                    */
     

/* ---------------------------------------------------------------- */
/*                         global variable                          */
/* ---------------------------------------------------------------- */

int   ShmID;                       /* shared memory ID              */
pid_t *ShmPTR;                     /* shared memory pointer         */
main()
{double load[3];
  if (getloadavg(load, 3) != -1) /*getloadavg is the function used to calculate and obtain the load a
verage*/
 {
 printf("load average : %f , %f , %f\n", load[0],load[1],load[2]);
  }
 float m;
 int n=2;
 long double g,h,i,pid,j,p,x=1,a=1;
 printf("enter the number whose exponential's is to be found\n");
 scanf("%Lf",&p);
 printf("enter the load average to be generated for the 1st minute\n");
 scanf("%f",&m);                               /*reading the input*/
 printf("finding (p^p^p^p....ptimes)\n");
 h=p;
 while(h>0)                 /*calculating the final exponent value*/
 {x=x*p;
   h--;
 }
 for(i=x;i>0;i--)           /*calculating the actual answer*/
 {a=a*p;
 }
 printf("the value is:%Lf\n",a);
 getloadavg(load,3);

 while(load[0]<m)
 {
   n=n*2;      /*increasing the number of child process*/
  goto x;
 }

/*
 printf("enter the number of child processes to be spwaned\n");
 scanf("%Lf",&n);
*/
x:
 while(load[0]<=m)
  {
   for(j=n;j>0;j--)
    {
      pid=fork();  /*creating the child process*/
      if(pid>0)
      wait();                 /*making the parent process wait*/
      if(pid <0)
      {printf("error:cannot fork!!");
       exit(1);
      }
   if (pid==0)                          /*child process*/
     {   long double f=1;
        MyKey   = ftok(".", 's');     /* create a shared memory segment*/
     ShmID   = shmget(MyKey, sizeof(pid_t), IPC_CREAT | 0666);
     ShmPTR  = (pid_t *) shmat(ShmID, NULL, 0);
     *ShmPTR = pid;                /* save my pid there             */
         break;
     
         printf("finding (p^p^p^p....ptimes)\n");
         h=p;
         while(h>0)
         {x=x*p;
          h--;
         }
         for(i=x;i>0;i--)
         {f=f*p;
         }
         printf("the value is:%Lf\n",a);
         if (getloadavg(load, 3) != -1)
         {
          printf("load average: %f, %f,%f\n",load[0],load[1],load[2]);
          printf("The number of child processes created:%d\n",n);
         }
         pid_t pid = getpid();
     key_t MyKey;

     if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
          printf("SIGINT install error\n");
          exit(1);
      } 
      MyKey   = ftok(".", 's');     /* create a shared memory segment*/
     ShmID   = shmget(MyKey, sizeof(pid_t), IPC_CREAT | 0666);
     ShmPTR  = (pid_t *) shmat(ShmID, NULL, 0);
     *ShmPTR = pid;                /* save my pid there             */
         break;
     }

    }
    getloadavg(load,3);
    if(load[0]<m)
    n=n*2;               /*increasing the forked processes*/
    continue;
  }


}
void  SIGINT_handler(int sig)
{
     signal(sig, SIG_IGN);
     printf("From SIGINT: just got a %d (SIGINT ^C) signal\n", sig);
      signal(sig, SIGINT_handler);
}
 
Old 08-04-2007, 10:04 AM   #5
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
Several points.
  1. expeliarmus, you have it right. ^C triggers SIGINT, not SIGKILL. But the rest of what ta0kira says is correct and useful:
    Quote:
    To stop the child processes, you will need to send a SIGSTOP signal to each one. You should also think about creating process groups to allow you to signal all processes in a group at one time.
  2. Inspection of your code shows that the signal handler is installed in the child process, not in the parent process. Is this what you want?
  3. Each child process will attach to the same shared memory segment, and place the content of variable pid there. One would think that the result would be that this shared memory segment would contain the pid of whatever child process was the latest one to get to this chunk of code. Is that what you want?
  4. But variable pid is 0, since this is the child process, so each child process will be storing 0 into this shared memory segment. Is this what you want?
  5. When a child process finishes doing child process stuff (the stuff inside the if(pid==0) block), it merrily continues with the getloadavg() call, the doubling of n, and the repeating of the whole while loop, which means that the child process will probably be doing a lot of fork()ing on its own. Is this what you want?
  6. Inspection of your code hints to me (I might be wrong) that the following behavior wouldn't happen:
    Quote:
    immediately on pressing ctrl +c ,and entering a desired load, the entire program terminates.
    It would seem to me that as soon as you type ^C, the program will terminate without letting you enter anything else, desired load or otherwise.
  7. I wanted to run the program to test my hypothesis in the previous point, but didn't, for two reasons.
    1. The program is incomplete. For one thing, MyKey is undeclared. For another, getloadavg() is undefined.
    2. The program is far more complex than necessary to illustrate the problem. That makes it difficult for others to come along and help. It also discourages others from running the program on their systems; I'm certainly not going to run it, because for all I know, I might have dangling unremoved shared memory segments.

      You may find that if you strip the program down so all it does is illustrate the problem, without all the exponentials and load averages and shared memory segments and stuff, just bare processes which loop, and no extraneous print statements to get in the way, you'll find the problem yourself, without having to wait for others to help. You'll certainly encourage them to read your code if they don't have to untangle it on the way.
  8. As a side note, if this code ever becomes part of a complete product, scanf() is not the way to go for input. Use fgets to get each string and parse it completely, being paranoid about checking every byte of input.

So if you strip the program down, make it compilable and linkable, and still can't find the problem with the stripped-down program, post it and let's take a look.
 
Old 08-06-2007, 01:04 AM   #6
expeliarmus
LQ Newbie
 
Registered: Jul 2007
Posts: 17

Original Poster
Rep: Reputation: 0
thanks loads wjevans!!i will follow your tips and post back if problems do arise.I really appreciate your help.thank you.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to rebuild the parent-child relationship of processes? whererush Programming 2 05-19-2006 02:17 PM
Parent child processes signal sharing iftiuk Programming 8 06-24-2004 01:32 PM
Getting a parent to communicate with its child -- fork() kamel Programming 3 06-02-2004 03:04 AM
parent and child processes skora Programming 5 11-02-2003 10:41 AM
about parent and child process winwar Solaris / OpenSolaris 3 07-23-2003 06:07 AM


All times are GMT -5. The time now is 10:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration