Part1: What is the difference between Single Process (program), Mutliprocesing and Mutlithreading?
To illustrate the difference we will consider an example.

#include <stdio.h>
#include <stdlib.h>

void first_function(int *);
void second_function(int *);
void final_function(int , int);

int i =0, j =0;
main()
{
         first_function(&i);
         second_function(&j);
         final_function(i,j);   
}

void first_function(int *num)
{
        int x,y,z;
        for(x=0; x< 10; x++)
        {
                printf("Inside the first_function\n");
                for(y=0; y< 1000; y++)
                z =z+1; /* introduce delay*/
                (*num)++;
        }
}

void second_function(int *num)
{
        int x,y,z;
        for(x=0; x< 10; x++)
        {
                printf("Inside the second_function\n");
                for(y=0; y< 1000; y++)
                z =z+1; /* introduce delay*/
                (*num)++;
        }
}

void final_function(int first, int second)
{
        int final_score;
        final_score = first + second ;
        printf("In final : first = %d, second = %d and final_score = %d\n",
        first, second, final_score);
}

The figure below shows the layout of this program in the virtual address memory. The various memory areas are
  • A read-only memory for the machine language instructions of the program
  • A read-write area for the global variables
  • A heap area for memory that is dynamically allocated (example malloc calls)
  • A stack on which local variables of current functions are maintained

Unix Multiprocessing:
We can rebuild the first program to illustrate the unix mutiprocessing. The main routine starts in a single process which is the parent process. The parent process then creates the child process to execute the first_function and another child process to execute the second_function routines. Then the parent process waits for both of its child process to finish and then calls final function .

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

void first_function(int *);
void second_function(int *);
void final_function(int,int);

int shared_mem_id;
int *shared_mem_ptr;
int *i, *j;

main()
{
    pid_t child1_pid, child2_pid;
    int state;
    /* initialise the shared memmory segment */
    shared_mem_id = shmget(IPC_PRIVATE, 2*sizeof(int),0);
    shared_mem_ptr = (int *)shmat(shared_mem_id, (void*)0, 0);

    /* giving the pointers to the variables */
    i = shared_mem_ptr;
    j = (shared_mem_ptr + 1);
    *i = 0;
    *j =0;

    /* start the first child process */
    if((child1_pid = fork())== 0)
    {
            /* job of first child*/
            first_function();
            exit();
     }

    /*start the second child process*/
    if((child2_pid = fork())== 0)
    {
        /* job of second child*/
        second_function();
        exit();
    }

    /*parent*/
    waitpid(child1_pid, state,0);
    waitpid(child2_pid, state,0);

    final_function(*i, *j);

}
void first_function(int *num)
{
    int x,y,z;
    for(x=0; x< 10; x++)
    {
        printf("Inside the first_function\n");
        for(y=0; y< 1000; y++)
        z =z+1; /* introduce delay*/
        (*num)++;
    }
}

void second_function(int *num)
{
     int x,y,z;
     for(x=0; x< 10; x++)
     {
            printf("Inside the second_function\n");
            for(y=0; y< 1000; y++)
            z =z+1; /* introduce delay*/
            (*num)++;
      }
}

void final_function(int first, int second)
{
      int final_score;
      final_score = first + second ;
      printf("In final : first = %d, second = %d and final_score = %d\n",
      first, second, final_score);
}
the UNIX system calls that create a new process is called fork. the fork creates the child process that is identical to its parent process at the time of function call of fork . following are the result
  • The child has its own process identifier, or PID
  • the fork call returns different values to child and parent processes (returns a value of 0 to child and child's PID to parent)
As depicted in the figure, as soon as the program forks into two different processes, the parent and child process execute independently unless there is synchronization.

Pthreads Concurrent Programming:
Pthreads is a standardized model for dividing a program into subtasks which can be run in parallel. We will repeat the example using Pthreads. The program starts with the main thread. Using the Pthread function calls, the creator thread spawns a thread to execute the first_function and another to execute the second_function routine.

#include <pthread.h>

void first_function(int *);
void second_function(int *);
void final_function(int,int);

int i=0; j=0;

main()
{
        pthread_t thread1, thread2;
        pthread_create(&thread1, NULL, (void*) first_function, (void*)&i);
        pthread_create(&thread2, NULL, (void*) second_function, (void*)&j);
        
        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
         
        final_function(i,j);
}

void first_function(int *num)
{
        int x,y,z;
        for(x=0; x< 10; x++)
        {
                printf("Inside the first_function\n");
                for(y=0; y< 1000; y++)
                z =z+1; /* introduce delay*/
                (*num)++;
        }
}

void second_function(int *num)
{
        int x,y,z;
        for(x=0; x< 10; x++)
        {
                printf("Inside the second_function\n");
                for(y=0; y< 1000; y++)
                z =z+1; /* introduce delay*/
                (*num)++;
        }
}

void final_function(int first, int second)
{
        int final_score;
        final_score = first + second ;
        printf("In final : first = %d, second = %d and final_score = %d\n",
        first, second, final_score);
}
The pthread_create uses the following parameters
  • A pointer to a buffer which identifies the newly created thread( Type of pthread_t*).
  • A pointer to a structure of type thread attribute object.
  • A pointer to routine at which the new thread will start executing
  • A pointer to a parameter to be passed to the routine at which the new thread starts
threads are created without replicating an entire process.