>

COSC330/530 - Parallel and Distributed Computing

Lecture 2 - Processes in Unix

Dr. Mitchell Welch


Reading


Summary


The Structure of a Program

int main(int argc, char* argv[]);


The Structure of a Program

int
main(int argc, char *argv[])
{
    int i;

    for (i = 0; i < argc; i++)      /* echo all command-line args */
        printf("argv[%d]: %s\n", i, argv[i]);
    exit(0);
}

The Structure of a Program

int main(int argc, char *argv[], char *envp[]);

The Structure of a Program


default-aligned image


The structure of a Program


The structure of a Program


default-aligned image


The structure of a Program

#include <stdlib.h>

// size_t is an integer (or long actually) type defined in stdlib
//Allocate a single block of size bytes
void *malloc(size_t size);

//Allocate an noObj length array of size bytes
void *calloc (size_t noObj, size_t size);

//Re-allocate the memory at ptr to be of newSize
void *realloc(void *ptr, size_T newSize);

//De-allocate and return the memory to the heap
void free(void *ptr)



Process Control Basics


Process Control Basics

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);


Process Control Basics

#include <sys/types.h>
#include <unistd.h>
// Calling Process ID
pid_t getpid(void);

// Parent of calling processes ID
pid_t getppid(void);

// Calling processes user ID
uid_t getuid(void); 

// Calling processes effective user ID
uid_t geteuid(void);

//  Calling processes group ID
gid_t getgid(void);

// Calling processes effective group ID
gig_t getegid(void);


Process Control Basics


Process Control Basics


Process Control Basics

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void){
   printf("Process ID: %ld\n", (long)getpid());
   printf("Parent process ID: %ld\n", (long)getppid());
   printf("Owner user ID: %ld\n", (long)getuid());
   printf("Effective user ID: %ld\n", (long)geteuid());
   return 0;
}


Process Control Basics

State Meaning
New Process is being created
Running The process' instructions are currently being executed
Blocked The process is waiting for an event (e.g. i/o).
Ready The process is waiting to run (i.e. can execute but currently scheduled of the processor)
Done The process is finished and is being de-allocated

Process Control Basics


Process Control Basics


default-aligned image


Process Control Basics


Process Control Basics


The fork() System Call

#include <sys/types.h>
 #include <unistd.h>
 pid_t fork ( void );   //Returns -1 on failure


The fork() System Call


The fork() System Call


The fork() System Call


The Make Utility


The Make Utility

COMPILER = gcc
CFLAGS = -Wall -pedantic

EXES = example01 forkex01  forkex02 forkex03 forkex04 forkex05 forkex06

all: ${EXES}


example01:  example01.c 
    ${COMPILER} ${CFLAGS}  example01.c -o example01
forkex01:  forkex01.c 
    ${COMPILER} ${CFLAGS}  forkex01.c -o forkex01
forkex02:  forkex02.c
    ${COMPILER} ${CFLAGS}  forkex02.c -o forkex02
forkex03:  forkex03.c
    ${COMPILER} ${CFLAGS}  forkex03.c -o forkex03
forkex04:  forkex04.c
    ${COMPILER} ${CFLAGS}  forkex04.c -o forkex04
forkex05:  forkex05.c
    ${COMPILER} ${CFLAGS}  forkex05.c -o forkex05
forkex06:  forkex06.c
    ${COMPILER} ${CFLAGS}  forkex06.c -o forkex06
clean: 
    rm -f *~ *.o ${EXES}


The Make Utility


Example Applications

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void){
  pid_t foo;
  foo = fork();
  printf("hey i'm %ld and my foo is %ld\n", 
          (long)getpid(),
          (long)foo);
  return 0;
}


Example Applications

foo = fork();
if(foo) 
  { /* parent code goes here */ }
else { /* child code goes here */ };

Example Applications

if((foo = fork()) < 0){ 
    /* fork error */
    perror("error in fork"); 
    exit(1); 
  } else if(foo){ 
    /* parent code here */ 
  } else { 
    /* child code  here */ 
}

/* code here will be executed by both  */
/* child and parent as long as they do */
/* not execute an call to exit or      */
/* abort in their code above           */

Example Applications


#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(void){ int i, n = 4; pid_t childpid; for (i = 1; i < n; ++i) if((childpid = fork()) < 0){ /* fork error */ perror("error in fork"); exit(EXIT_FAILURE); } else if(childpid){ /* parent code */ * break; } else { /* child code */ } /* mutual code */ printf("This is process %ld with parent %ld\n", (long)getpid(), (long)getppid()); return 0; }

Example Applications

turing.Examples> forkex02
This is process 25906 with parent 21711
This is process 25907 with parent 25906
This is process 25909 with parent 25908
turing.Examples> This is process 25908 with parent 25907
Note that the prompt returned before one of the spawned processes.

Example Applications

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void){
  int i, n = 4;
  pid_t childpid;
  for (i = 1; i < n;  ++i)
    if((childpid = fork()) < 0){ 
      /* fork error */
      perror("error in fork"); 
      exit(EXIT_FAILURE); 
    } else if(childpid){ 
      /* parent code */ 
    } else { 
      /* child code  */ 
*      break; 
    }
  /* mutual code */   
  printf("This is process %ld with parent %ld\n",
         (long)getpid(), (long)getppid());
  return 0;
}

Example Applications

turing.Examples> forkex03
This is process 25977 with parent 25975
This is process 25976 with parent 25975
This is process 25975 with parent 21711
This is process 25978 with parent 25975
turing.Examples>

Example Applications

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void){
  int i, n = 4;
  pid_t childpid;
  for (i = 1; i < n;  i++)
    if((childpid = fork()) < 0){ 
      /* fork error */
      perror("error in fork"); 
      exit(EXIT_FAILURE); 
    } else if(childpid){ 
*      /* parent code */ 
    } else { 
*      /* child code  */ 
    } 
  /* mutual code */
  printf("This is process %ld with parent %ld\n",
         (long)getpid(), (long)getppid());
  return 0;
}

Example Applications

turing.Examples> forkex04
This is process 26140 with parent 21711
This is process 26142 with parent 26140
This is process 26143 with parent 26141
This is process 26141 with parent 26140
turing.Examples> This is process 26146 with parent 1
This is process 26147 with parent 1
This is process 26145 with parent 1
This is process 26144 with parent 1

Example Applications

/*See example07.c for includes*/

int main(void){
  int i, n = 4;
  pid_t childpid;
  int status;
  for (i = 1; i < n;  ++i)
    if((childpid = fork()) < 0){ 
      /* fork error */
      perror("error in fork"); 
      exit(EXIT_FAILURE); 
    } else if(childpid){ 
      /* parent code */ 
    } else { 
      /* child code  - sleep to force some orphans*/ 
      sleep(1);
      break; 
    }
  /* mutual code */   
  printf("This is process %ld with parent %ld\n",
         (long)getpid(), (long)getppid());
  return 0;
}


Example Applications

./example07
This is process 19518 with parent 22381
[turing cosc330] $ This is process 19523 with parent 1
This is process 19521 with parent 1
This is process 19522 with parent 1


Example Applications

/*See example07.c for includes*/
int main(void){
  int i, n = 4;
  pid_t childpid;
  int status;
  for (i = 1; i < n;  ++i)
    if((childpid = fork()) < 0){ 
      /* fork error */
      perror("error in fork"); 
      exit(EXIT_FAILURE); 
    } else if(childpid){ 
      /* parent code */ 
    } else { 
      /* child code  - sleep to force some orphans*/ 
      sleep(1);
       break; 
    }  
  printf("This is process %ld with parent %ld\n",
         (long)getpid(), (long)getppid());
  /* Very simple wait with no error checking */
  for (i=1; i < n; i++){
    wait(&status);
  }
  return 0;
}

Example Applications

turing cosc330] $ ./example07
This is process 6039 with parent 22381
This is process 6043 with parent 6039
This is process 6042 with parent 6039
This is process 6044 with parent 6039
[turing cosc330] $ 

Example Applications

int     globvar = 6;        /* external variable in initialized data */
char    buf[] = "a write to stdout\n";

int main(void){
    int var;            /* automatic variable on the stack */
    pid_t   pid;
    var = 88;
    if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
        err_sys("write error");
    printf("before fork\n");    /* we don't flush stdout */

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {      /* child */
        globvar++;      /* modify variables */
        var++;
    } else {
        sleep(2);       /* parent */
    }
    printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar,var);
    exit(0);
}



Summary

* Examples

Questions?


Reading