ΠΕΡΙΕΧΟΜΕΝΑ

 

1.  abort( )  

2.  atexit( )  

3.  Η οικογένεια συναρτήσεων exec 

4.  Η οικογένεια συναρτήσεων spawn…  

 

 

 

Η. PROCESS CONTROL  FUNCTIONS

 

 

 

1.  abort( ) 

 

            Τα πρωτότυπά της βρίσκονται στα <process.h> και <stdlib.h>:

 

void abort( )

 

            Προκαλεί άμεσο τερματισμό ενός προγράμματος.

 

Π.χ.:         #include <process.h>

                 main( )

                 {

                   for(;;)

                      if(getch( ) == ‘A’) abort( );

                 }

 

            Το πρόγραμμα ορίζει έναν ατέρμονα βρόγχο ο οποίος τερματίζεται αν πατηθεί  Α.

 

 

 

2.  atexit( ) 

 

            Το πρωτότυπό της βρίσκεται στο <stdlib.h>:

 

int atexit (func)   void (*func) ( )

 

            Η συνάρτηση atexit( ) καθορίζει τη συνάρτηση func, να είναι η συνάρτηση, που θα καλείται σε περίπτωση ομαλού τερματισμού του προγράμματος. Η atexit( ) επιστρέφει 0,  αν η συνάρτηση είναι Terminating Function και 1 σε άλλη περίπτωση. Μπορούν να κληθούν ως 32 συναρτήσεις. Αυτές καλούνται ανάποδα απ’ ότι δηλώθηκαν, δηλ. First in, Last out.

 

Π.χ.:              main( )  {

                        void done( );

                        if (atexit (done) ) printf (“Error”);

                     }

                     void done ( )   {

                        printf (“Hello There”);

                     }

 

 

 

3.  Η οικογένεια συναρτήσεων exec 

 

            Τά πρωτότυπά τους βρίσκονται στο <process.h>:

 

int execl (char *fname, char *arg0, … , char *argN, NULL)

int execle (char *fname, char *arg0, … , char *argN, NULL, char *envp[ ])

int execlp (char *fname, char *arg0, … , char *argN, NULL)

int execpe (char *fname, char *arg0, … , char *argN, NULL, char *envp[ ])

int execp (char *fname, char *arg[ ])

int execpe (char *fname, char *arg[ ], char *envp[ ])

int execv (char *fname, char *arg[ ])

int execve (char *fname, char *arg[ ], char *envp[ ])

 

Οι συναρτήσεις αυτές χρησιμοποιούνται για να εκτελέσουν άλλα προγράμματα. Το πρόγραμμα αυτό λέγεται child process file και δείχνεται από τον pointer fname. Οι παράμετροι στην child process δείχνονται είτε από το arg0…argN, είτε από τον πίνακα arg[ ]. Ένα environment string πρέπει να δείχνεται από το envp (τα arguments δείχνονται από το argv στην child process).

 

            Αν δεν υπάρχει προέκταση ή τελεία στο fname, γίνεται πρώτα ανίχνευση για αρχείο με αυτό το όνομα. Αν αυτό αποτύχει, προστίθεται η προέκταση .EXE και η ανίχνευση επαναλαμβάνεται ξανά. Αν το extension ορίζεται, η ανίχνευση γίνεται για το συγκεκριμένο string. Τέλος, αν υπάρχει τελεία και όχι extension, η ανίχνευση γίνεται για το αρχείο, που βρίσκεται στα αριστερά του ονόματος.

 

            Ο ακριβής τρόπος δράσης της exec… εξαρτάται από την έκδοση της συνάρτησης που χρησιμοποιούμε. Η exec… διαθέτει διαφορετικές καταλήξεις, οι οποίες ορίζουν τη λειτουργία της. Μία κατάληξη μπορεί να περιέχει ανάλογα ένα ή δύο χαρακτήρες.

 

            Συναρτήσεις που περιέχουν ένα p στην κατάληξη, ελέγχουν για την child process και στα directory που ορίζονται από το DOS PATH. Αν δεν υπάρχει το p, τότε ο έλεγχος γίνεται μόνο στο current και στο root directory.

 

            Αν υπάρχει ένα 1, τότε οι παράμετροι στην child process θα περάσουν ξεχωριστά μία – μία. Αυτό το χρησιμοποιούμε όταν ξέρουμε πόσες παράμετροι θα περαστούν. Σημειώνουμε ότι η τελευταία παράμετρος πρέπει να είναι NULL.

 

            Αν υπάρχει e, δείχνει ότι ένα ή περισσότερα environmental strings θα περαστούν στην child process. Η παράμετρος envp[ ] είναι ένας πίνακας από string pointers. Κάθε string που δείχνεται από τα στοιχεία του πίνακα πρέπει να έχει τη φόρμα:                    environment variable = value.

 

            Ο τελευταίος pointer στον πίνακα πρέπει να είναι NULL. Αν ο πρώτος pointer είναι NULL, τότε το child κληρονομεί το ίδιο περιβάλλον σαν τον parent.

 

            Είναι σημαντικό ότι τα ανοιχτά αρχεία στη διάρκεια του exec… μένουν ανοιχτά και στο child.

 

            Αν η exec έχει επιτυχή εκτέλεση δεν επιστρέφει τιμή. Σε περίπτωση αποτυχίας επιστρέφει –1 και θέτει το errno σε μία από τις παρακάτω τιμές:

 

 

Macro

 

EZBIG

EACCES

EMFILE

ENOENT

ENOEXEC

ENOMEM

Έννοια

 

Too Many Arguments

Access To Child Process File Denied

Too Many Files

File Not Found

Exec Format Error

Not Enough Free Memory



Π.χ.:              #include <stdio.h>

                      #include <process.h>

                      main( )

                      {

                        execl ( “Test.Exe”, “Test.Exe”, “hello”, “10”, NULL);

                      }

 

                      main(int argc, char *argv[ ] )

                      {

                        printf(“this program is executed with this command line:”);

                        printf ( “arguments: “);

                        printf (argv[1]);

                        printf(“%d”, atoi(argv[2]));

                      }

 

 

 

4.  Η οικογένεια συναρτήσεων spawn… 

 

            Το πρωτότυπό της βρίσκεται στο <process.h>:

 

int spawnl (int mode, char *fname, char *arg0, … , char *argN, NULL)

int spawnle (int mode, char *fname, char *arg0,… , char *argN, NULL, char *envp[ ])

int spawnlp (int mode, char *fname, char *arg0, … , char *argN, NULL)

int spawnlpe (int mode, char *fname, char *arg0,… , char *argN, NULL, char *envp[ ])

int spawnp (int mode, char *fname, char *arg[ ])

int spawnpe (int mode, char *fname, char *arg[ ], char *envp[ ])

int spawnv (int mode, char *fname, char arg[ ])

int spawnve (int mode, char *fname, char *arg[ ], char *envp[ ])

 

Αυτό το group συναρτήσεων χρησιμοποιείται για να εκτελέσει άλλα προγράμματα. Η διαφορά αυτών των συναρτήσεων από τις exec συναρτήσεις, είναι ότι οι spawn… δεν αντικαθιστούν το parent program στη μνήμη (αντίθετα με τις exec… , που το αντικαθιστούν πλήρως). Το όνομα του προγράμματος είναι το fname. Αν υπάρχουν παράμετροι αυτές δείχνονται από τα arg0…argN ή τον πίνακα arg[ ]. Αν χρειαστεί να περαστεί ένα environment string, αυτό δείχνεται από την envp (οι παράμετροι θα δείχνονται από την argv στην child process).

 

            Η παράμετρος mode διευκρινίζει πως θα εκτελεστεί το child process program. Μπορεί να έχει μία από τις παρακάτω τιμές (ορισμένες στο header file process.h):

 

 

Macro

 

P_WAIT

P_NOWAIT

P_OVERLAY

 

Execution Mode

 

Suspends parent process until the child has finished executing

Executes both the parent and the child concurrently – not implemented – in TURBO C

Replaces the parent process in memory

 


 

Όπως βλέπουμε, η P_NOWAIT είναι προς το παρόν μη διαθέσιμη, έτσι συνήθως χρησιμοποιούμε την P_WAIT σαν value mode. Πάντως αν θέλουμε να αντικαταστήσουμε το parent πρόγραμμα, είναι καλύτερο να χρησιμοποιήσουμε την exec… . Αν χρησιμοποιηθεί η επιλογή P_WAIT μετά το τέλος του child, η ροή του ελέγχου επιστρέφει στο parent και μάλιστα στην επόμενη γραμμή μετά την κλήση του spawn.

 

            Αν δεν υπάρχει προέκταση ή τελεία στο string, που δείχνει το fname, γίνεται πρώτα ανίχνευση για αρχείο με αυτό το όνομα. Αν αυτό αποτύχει, προστίθεται η προέκταση .EXE και η ανίχνευση γίνεται για το συγκεκριμένο string. Τέλος, αν υπάρχει τελεία και όχι extension, η ανίχνευση γίνεται για το αρχείο, που βρίσκεται στα αριστερά του ονόματος.

           

            Ο ακριβής τρόπος αντίδρασης της spawn… εξαρτάται από την έκδοση της εντολής που χρησιμοποιούμε. Η spawn διαθέτει διαφορετικές καταλήξεις, οι οποίες ορίζουν τη λειτουργία της. Μία κατάληξη μπορεί να περιέχει ανάλογα ένα ή δύο χαρακτήρες.

 

            Συναρτήσεις που περιέχουν ένα p στην κατάληξη, ελέγχουν για την child process και στα directory, που ορίζονται από το DOS PATH. Αν δεν υπάρχει το p, ο έλεγχος γίνεται μόνο στο current και στο root directory.

 

            Αν υπάρχει ένα 1, τότε οι παράμετροι στην child process θα περάσουν ξεχωριστά μία – μία. Αυτό το χρησιμοποιούμε όταν ξέρουμε πόσες παράμετροι θα περαστούν. Σημειώνουμε ότι η τελευταία παράμετρος πρέπει να είναι NULL (το NULL ορίζεται στο <stdio.h>).

 

            Αν υπάρχει ν στην κατάληξη, τότε οι παράμετροι θα περαστούν σε πίνακα. Αυτό το χρησιμοποιούμε όταν δεν ξέρουμε πόσες ακριβώς παράμετροι θα περαστούν.

 

            Αν υπάρχει e, στην κατάληξη, ορίζει ότι ένα ή περισσότερα environmental strings θα περαστούν στην child process. Η παράμετρος envp[ ] είναι ένας πίνακας από string pointers. Κάθε string στον πίνακα πρέπει να έχει τη μορφή:                                                             environment variable = value.

 

            Ο τελευταίος pointer στον πίνακα πρέπει να είναι NULL. Αν το πρώτο στοιχείο του πίνακα είναι NULL, τότε το child κληρονομεί το ίδιο περιβάλλον σαν τον parent.

 

            Υπενθυμίζεται ότι όσα αρχεία ανοίξουν στο parent, μένουν ανοιχτά και στο child.

 

            Αν η spawn έχει επιτυχή εκτέλεση δεν επιστρέφει τιμή. Σε περίπτωση αποτυχίας επιστρέφει –1 και θέτει το errno σε μία από τις παρακάτω τιμές:

 

 

Macro

 

EZBIG

EACCES

EMFILE

ENOENT

ENOEXEC

ENOMEM

 

Έννοια

 

Too Many Arguments

Access To Child Process File Denied

Too Many File

File Not Found

Exec Format Error

Not Enough Free Memory

 


 

            Μία spawned διαδικασία μπορεί να κάνει spawn και σε άλλες διαδικασίες. Το όριο των nested spawn ορίζεται από την ελεύθερη RAM και το μέγεθος των προγραμμάτων.

 

Π.χ.:         #include <stdio.h>              / * Parent Process * /

                 #include <process.h>

                 main( )

                 {

                   printf ( “In Parent \n”);

                   spawnl (P_WAIT, “Test.Exe”, “Test.Exe”, “hello”, “10”, NULL);

                   printf (“\n Back in Parent”);

                 }

                 #include <stdio.h>              / * First Child * /

                 #include <process.h>

                 main (int argc, char *argv[ ] )

                 {

                   printf (“First Child Process executed with this command line: “);

                   printf (“Arguments: “);

                   printf (argv [1]);

                   printf (“%d”, atoi (argv[2])); spawnl(P_WAIT, “Test2.Exe”, NULL);

                   printf (“\n Back if First Child Process”);

                 }

                 main( )

                 {

                   printf(“In Second Child Process”);

                 }

 

            Το παράδειγμα αυτό περιλαμβάνει ένα parent program, το οποίο καλεί ένα child. Το child τυπώνει τις παραμέτρους κλήσεις του και καλεί ένα δεύτερο child. Μετά το τέλος του δεύτερου childe επιστρέφει στο πρώτο child και έπειτα στο parent.