Find the answer to your Linux question:
Results 1 to 10 of 10
I create n processes with fork(). Every child must calculate something and write result in shared memory. For each child i use semaphore and when child is writing something to ...
  1. #1
    Just Joined!
    Join Date
    Jan 2010
    Posts
    4

    Fork, semctl, wait

    I create n processes with fork(). Every child must calculate something and write result in shared memory. For each child i use semaphore and when child is writing something to memory, semaphore is red(value 0), after first child is done, it calls signalize(semaphores value is 1) so next child can start with writing in critical part . Now I dont know how to wait, that all childs end with writing without using wait call? How could i wait for all childs to complete their work, so father can print the results from memory?

    Thanks

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    When each child terminates, the parent will get a SIGCHLD, so it can wait until all the child processes are done, at which time it can print the results. It should not need to do anything except create/destroy the semaphore.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Jan 2010
    Posts
    4
    Ok.. i do like this..
    for(i=0; i<10; i++){
    if(fork()==0){
    W(semid, i) puts semaphore on 0
    /*here is something written to memory
    */
    S(semid,i) signalizes so next child can use semaphore
    exit(0);
    }

    after this i have to check if all childs are terminated.. so how does this SIGCHLD checking looks in code..

    thanks for help
    and when

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    The man page for wait():
    Code:
    WAIT(2)                    Linux Programmer’s Manual                   WAIT(2)
    
    NAME
           wait, waitpid - wait for process to change state
    
    SYNOPSIS
           #include <sys/types.h>
           #include <sys/wait.h>
    
           pid_t wait(int *status);
           pid_t waitpid(pid_t pid, int *status, int options);
           int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
    
    DESCRIPTION
           All  of  these  system  calls are used to wait for state changes in a
           child of the calling process, and obtain information about the  child
           whose  state  has  changed.   A state change is considered to be: the
           child terminated; the child was stopped by a signal; or the child was
           resumed by a signal.  In the case of a terminated child, performing a
           wait allows the system to release the resources associated  with  the
           child;  if a wait is not performed, then terminated the child remains
           in a "zombie" state (see NOTES below).
    
           If a child has already changed state, then these calls return immedi-
           ately.   Otherwise they block until either a child changes state or a
           signal handler interrupts the call (assuming that  system  calls  are
           not  automatically  restarted  using  the  SA_RESTART  flag of sigac-
           tion(2)).  In the remainder of this page, a  child  whose  state  has
           changed and which has not yet been waited upon by one of these system
           calls is termed waitable.
    
       wait() and waitpid()
           The wait() system call suspends  execution  of  the  current  process
           until  one  of  its  children  terminates.  The call wait(&status) is
           equivalent to:
    
               waitpid(-1, &status, 0);
    
           The waitpid() system call suspends execution of the  current  process
           until  a  child  specified  by  pid  argument  has changed state.  By
           default, waitpid() waits  only  for  terminated  children,  but  this
           behaviour is modifiable via the options argument, as described below.
    
           The value of pid can be:
    
           < -1   meaning wait for any child process whose process group  ID  is
                  equal to the absolute value of pid.
    
           -1     meaning wait for any child process.
    
           0      meaning  wait  for any child process whose process group ID is
                  equal to that of the calling process.
    
           > 0    meaning wait for the child whose process ID is  equal  to  the
                  value of pid.
    
           The  value  of options is an OR of zero or more of the following con-
           stants:
    
           WNOHANG
                  return immediately if no child has exited.
    
           WUNTRACED
                  also return if  a  child  has  stopped  (but  not  traced  via
                  ptrace(2)).   Status for traced children which have stopped is
                  provided even if this option is not specified.
    
           WCONTINUED
                  (Since Linux 2.6.10) also return if a stopped child  has  been
                  resumed by delivery of SIGCONT.
    
           (For Linux-only options, see below.)
    
           The  WUNTRACED  and  WCONTINUED  options  are  only  effective if the
           SA_NOCLDSTOP flag has not been set for the SIGCHLD signal (see sigac-
           tion(2)).
    
           If  status is not NULL, wait() and waitpid() store status information
           in the int to which it points.  This integer can  be  inspected  with
           the  following  macros (which take the integer itself as an argument,
           not a pointer to it, as is done in wait() and waitpid()!):
    
           WIFEXITED(status)
                  returns true if the child terminated  normally,  that  is,  by
                  calling exit(3) or _exit(2), or by returning from main().
    
           WEXITSTATUS(status)
                  returns  the  exit  status of the child.  This consists of the
                  least significant 16-8 bits of the status  argument  that  the
                  child specified in a call to exit() or _exit() or as the argu-
                  ment for a return statement in main().  This macro should only
                  be employed if WIFEXITED returned true.
    
           WIFSIGNALED(status)
                  returns  true if the child process was terminated by a signal.
    
           WTERMSIG(status)
                  returns the number of the signal that caused the child process
                  to  terminate.  This  macro should only be employed if WIFSIG-
                  NALED returned true.
    
           WCOREDUMP(status)
                  returns true if the child produced a core  dump.   This  macro
                  should  only  be  employed if WIFSIGNALED returned true.  This
                  macro is not specified in POSIX.1-2001 and is not available on
                  some  Unix  implementations (e.g., AIX, SunOS).  Only use this
                  enclosed in #ifdef WCOREDUMP ... #endif.
    
           WIFSTOPPED(status)
                  returns true if the child process was stopped by delivery of a
                  signal;  this is only possible if the call was done using WUN-
                  TRACED or when the child is being traced (see ptrace(2)).
    
           WSTOPSIG(status)
                  returns the number of the signal which  caused  the  child  to
                  stop.   This  macro  should  only  be  employed  if WIFSTOPPED
                  returned true.
    
           WIFCONTINUED(status)
                  (Since Linux 2.6.10) returns true if  the  child  process  was
                  resumed by delivery of SIGCONT.
    
       waitid()
           The  waitid() system call (available since Linux 2.6.9) provides more
           precise control over which child state changes to wait for.
    
           The idtype and id arguments select the child(ren)  to  wait  for,  as
           follows:
    
           idtype == P_PID
                  Wait for the child whose process ID matches id.
    
           idtype == P_PGID
                  Wait for any child whose process group ID matches id.
    
           idtype == P_ALL
                  Wait for any child; id is ignored.
    
           The  child  state  changes  to wait for are specified by ORing one or
           more of the following flags in options:
    
           WEXITED
                  Wait for children that have terminated.
    
           WSTOPPED
                  Wait for children that have been stopped by delivery of a sig-
                  nal.
    
           WCONTINUED
                  Wait  for (previously stopped) children that have been resumed
                  by delivery of SIGCONT.
    
           The following flags may additionally be ORed in options:
    
           WNOHANG
                  As for waitpid().
    
           WNOWAIT
                  Leave the child in a waitable state; a later wait call can  be
                  used to again retrieve the child status information.
    
           Upon successful return, waitid() fills in the following fields of the
           siginfo_t structure pointed to by infop:
    
           si_pid The process ID of the child.
    
           si_uid The real user ID of the child.  (This field is not set on most
                  other implementations.)
    
           si_signo
                  Always set to SIGCHLD.
    
           si_status
                  Either  the exit status of the child, as given to _exit(2) (or
                  exit(3)), or the signal that caused the  child  to  terminate,
                  stop, or continue.  The si_code field can be used to determine
                  how to interpret this field.
    
           si_code
                  Set to one of: CLD_EXITED (child called _exit(2));  CLD_KILLED
                  (child  killed  by signal); CLD_STOPPED (child stopped by sig-
                  nal); or CLD_CONTINUED (child continued by SIGCONT).
    
           If WNOHANG was specified in options and there were no children  in  a
           waitable  state, then waitid() returns 0 immediately and the state of
           the siginfo_t structure pointed to by infop is unspecified.  To  dis-
           tinguish  this  case from that where a child was in a waitable state,
           zero out the si_pid field before the call and check  for  a  non-zero
           value in this field after the call returns.
    
    RETURN VALUE
           wait():  on  success, returns the process ID of the terminated child;
           on error, -1 is returned.
    
           waitpid(): on success, returns the process  ID  of  the  child  whose
           state has changed; on error, -1 is returned; if WNOHANG was specified
           and no child(ren) specified by pid has yet changed state, then  0  is
           returned.
    
           waitid():  returns  0  on  success or if WNOHANG was specified and no
           child(ren) specified by id has yet changed state;  on  error,  -1  is
           returned.
    
           Each of these calls sets errno to an appropriate value in the case of
           an error.
    
    ERRORS
           ECHILD (for wait()) The calling process does not have  any  unwaited-
                  for children.
    
           ECHILD (for  waitpid()  or  waitid())  The  process  specified by pid
                  (waitpid()) or idtype and id (waitid()) does not exist  or  is
                  not  a  child  of  the  calling process.  (This can happen for
                  one’s own child if the action for SIGCHLD is set  to  SIG_IGN.
                  See also the LINUX NOTES section about threads.)
    
           EINTR  WNOHANG  was  not set and an unblocked signal or a SIGCHLD was
                  caught.
    
           EINVAL The options argument was invalid.
    
    NOTES
           A child that terminates, but has not been waited for becomes a  "zom-
           bie".   The  kernel  maintains a minimal set of information about the
           zombie process (PID, termination status, resource usage  information)
           in order to allow the parent to later perform a wait to obtain infor-
           mation about the child.  As long as a zombie is not removed from  the
           system  via  a wait, it will consume a slot in the kernel process ta-
           ble, and if this table fills, it will not be possible to create  fur-
           ther  processes.   If  a parent process terminates, then its "zombie"
           children (if any) are adopted by init(8),  which  automatically  per-
           forms a wait to remove the zombies.
    
           POSIX.1-2001  specifies  that if the disposition of SIGCHLD is set to
           SIG_IGN or the SA_NOCLDWAIT flag  is  set  for  SIGCHLD  (see  sigac-
           tion(2)),  then  children  that terminate do not become zombies and a
           call to wait() or waitpid() will block until all children have termi-
           nated,  and  then fail with errno set to ECHILD.  (The original POSIX
           standard left the behaviour of setting SIGCHLD  to  SIG_IGN  unspeci-
           fied.)  Linux 2.6 conforms to this specification.  However, Linux 2.4
           (and earlier) does not: if a wait() or waitpid() call is  made  while
           SIGCHLD  is  being  ignored,  the call behaves just as though SIGCHLD
           were not being ignored, that is, the call blocks until the next child
           terminates  and then returns the process ID and status of that child.
    
    LINUX NOTES
           In the Linux kernel, a kernel-scheduled thread is not a distinct con-
           struct  from a process. Instead, a thread is simply a process that is
           created using the Linux-unique clone(2) system call;  other  routines
           such  as  the  portable  pthread_create(3) call are implemented using
           clone(2).  Before Linux 2.4, a thread was just a special  case  of  a
           process,  and as a consequence one thread could not wait on the chil-
           dren of another thread, even when the  latter  belongs  to  the  same
           thread  group.   However,  POSIX  prescribes  such functionality, and
           since Linux 2.4 a thread can, and by default will, wait  on  children
           of other threads in the same thread group.
    
           The  following  Linux-specific options are for use with children cre-
           ated using clone(2); they cannot be used with waitid():
    
           __WCLONE
                  Wait for "clone" children only.   If  omitted  then  wait  for
                  "non-clone"  children  only.   (A  "clone"  child is one which
                  delivers no signal, or a signal other than SIGCHLD to its par-
                  ent  upon  termination.)   This option is ignored if __WALL is
                  also specified.
    
           __WALL (Since Linux 2.4) Wait for all children,  regardless  of  type
                  ("clone" or "non-clone").
    
           __WNOTHREAD
                  (Since Linux 2.4) Do not wait for children of other threads in
                  the same thread group. This was the default before Linux  2.4.
    
    EXAMPLE
           The following program demonstrates the use of fork(2) and waitpid(2).
           The program creates a child process.  If no command-line argument  is
           supplied  to the program, then the child suspends its execution using
           pause(2), to allow the user to send signals to the child.  Otherwise,
           if  a command-line argument is supplied, then the child exits immedi-
           ately, using the integer supplied on the command  line  as  the  exit
           status.   The  parent process executes a loop that monitors the child
           using waitpid(2), and uses the W*() macros described above to analyse
           the wait status value.
    
           The following shell session demonstrates the use of the program:
    
           $ ./a.out &
           Child PID is 32360
           [1] 32359
           $ kill -STOP 32360
           stopped by signal 19
           $ kill -CONT 32360
           continued
           $ kill -TERM 32360
           killed by signal 15
           [1]+  Done                    ./a.out
           $
    
           #include <sys/wait.h>
           #include <stdlib.h>
           #include <unistd.h>
           #include <stdio.h>
    
           int
           main(int argc, char *argv[])
           {
               pid_t cpid, w;
               int status;
    
               cpid = fork();
               if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); }
    
               if (cpid == 0) {            /* Code executed by child */
                   printf("Child PID is %ld\n", (long) getpid());
                   if (argc == 1)
                       pause();                    /* Wait for signals */
                   _exit(atoi(argv[1]));
    
               } else {                    /* Code executed by parent */
                   do {
                       w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                       if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }
    
                       if (WIFEXITED(status)) {
                           printf("exited, status=%d\n", WEXITSTATUS(status));
                       } else if (WIFSIGNALED(status)) {
                           printf("killed by signal %d\n", WTERMSIG(status));
                       } else if (WIFSTOPPED(status)) {
                           printf("stopped by signal %d\n", WSTOPSIG(status));
                       } else if (WIFCONTINUED(status)) {
                           printf("continued\n");
                       }
                   } while (!WIFEXITED(status) && !WIFSIGNALED(status));
                   exit(EXIT_SUCCESS);
               }
           }
    
    CONFORMING TO
           SVr4, 4.3BSD, POSIX.1-2001.
    
    SEE ALSO
           _exit(2),  clone(2),  fork(2), kill(2), ptrace(2), sigaction(2), sig-
           nal(2), wait4(2), pthread_create(3), signal(7)
    
    Linux                             2004-11-11                           WAIT(2)
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Jan 2010
    Posts
    4
    I can't use wait()? This is what i am asking you..what to use so it would work same as wait()?

  6. #6
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    Why can't you use wait? An alternative would be to set up a signal handler to process SIGCHLD events, but that is not optimal. The wait() functions were designed for exactly the purpose you mention.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  7. #7
    Just Joined!
    Join Date
    Jan 2010
    Posts
    4
    This is our task. I know how to use wait..but we can't use wait in this case. Is there any chance i could check if all child processes finished. Or if all semaphors are set to 1 or smt?

  8. #8
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    An explanation of why you can't use wait() would be helpful. As I said, you can set up the father/parent process with a signal handler and know when each child is finished. A simple counter would be fine. One of the reasons to use wait() is to keep zombie processes from cluttering the system. They will stay around until either the parent finishes them with wait(), or the parent dies.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  9. #9
    Just Joined!
    Join Date
    May 2008
    Posts
    36
    Quote Originally Posted by spoofG View Post
    This is our task. I know how to use wait..but we can't use wait in this case. Is there any chance i could check if all child processes finished. Or if all semaphors are set to 1 or smt?
    Is this some sort of homework assignment?

    Anyway, the obvious way to do it without using wait() is to set up a while loop that keeps going while the semaphores aren't all 1.

    That's the ugly solution. A nicer one is a signal handler and the nicest is wait()

  10. #10
    Super Moderator MikeTbob's Avatar
    Join Date
    Apr 2006
    Location
    Texas
    Posts
    7,144
    Quote Originally Posted by trutheality View Post
    Is this some sort of homework assignment?

    Anyway, the obvious way to do it without using wait() is to set up a while loop that keeps going while the semaphores aren't all 1.

    That's the ugly solution. A nicer one is a signal handler and the nicest is wait()
    I agree. Homework and school assignments are forbidden here on these forums...we'll be keeping and eye on this thread.
    I do not respond to private messages asking for Linux help, Please keep it on the forums only.
    All new users please read this.** Forum FAQS. ** Adopt an unanswered post.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...