Wednesday 4 December 2013

C program to demonstrate working of Turing Machine

Leave a Comment
        Turing machine is a imaginary device with infinite tape which manipulates the symbols on tape to get required result on the basis of specified rule. Instead of going in a theoretical detail we will concentrate on practical implementation of it.
        Here we are going to demonstrate "n mod 2" implementation using Turing machine. In this example we take input from user (number 'n') and then create an array with size 'n+2' containing "NULL" followed by all 1s followed by "NULL". At first pointer is pointing to the left most element of array which is initial of array. Then by traversing right go to the element of array which is "NULL" and stop at that point as shown in the figure below. Then traverse left. If '1' comes while traversing left, replace '1' with "NULL" and alter the flag between 0 and 1. At last if you get flag as '1' then it can be considered as ODD number otherwise (flag=0 i.e. remain as it is) it is EVEN number.
       Download program NMOD2.c.


#include"stdio.h"
#include"stdlib.h"
int main()
{
 int i,n,flag=0;
 char *ptr;
 printf("\n Enter number\n");
 scanf("%d",&n);
 ptr= (char *)malloc((n+2)*sizeof(char));

 for(i = 0; i < n+2; i++)
 {
  if(i == 0 || i == n+1)
  {
   ptr[i]='\0';
  }
  else
  {
   ptr[i]='1';
  }
 }

 ptr=ptr+1;
 while(*ptr != '\0')
 {
  ptr = ptr+1;
 }
 ptr = ptr-1;

 while(*ptr != '\0')
 {
  if(*ptr == '1')
  *ptr='\0';

  if(flag == 0)
  {
   flag = 1;
  }

  else if(flag == 1)
  {
   flag = 0;
  }
  else
  {
  }
  ptr=ptr-1;
 }
 
 if(flag == 1)
  printf("This is ODD Number\n");
 else
  printf("This is EVEN Number\n" );
 return 0;
}


Read More...

Friday 25 October 2013

Calculate time in C or CPP program

Leave a Comment
      There are many methods to calculate time taken by part of execution or whole program in gcc as mention below.
Calculate Time in C
       Out of this time() function gives the accuracy up-to seconds. But generally we require accuracy in micro or nano seconds to check the little difference. So we are going to see the time calculation using clock_gettime() and gettimeofday() function for well known application matrix multiplication.
      The programs matrix_mul_gettimeofday.c given below show the time calculated using gettimeofday() function

#include"stdio.h"
#include"sys/time.h"
#include"stdlib.h"
#define N 4000
#define X 300
#define Y 200

int main()
{
 int sum = 0,i,j,k;
 int **mat1; //declared mat1[X][N]
 int **mat2; //declare mat2[N][Y]
  int **mat_res; //resultant matrix become mat_res[X][Y]
  struct timeval tim;
  double t1,t2,result;
  
  /*----------------------------------------------------*/
 //create array of pointers(Rows)
  mat1 =(int **) malloc(X*sizeof(int*));
  mat2 =(int **)malloc(N*sizeof(int*));
  mat_res=(int **)malloc(X*sizeof(int*));
  /*----------------------------------------------------*/
  
  /*--------------------------------------------------------------------------------*/
 //allocate memory for each Row pointer
  for(i=0; i < X; i++)
  {
   mat1[i] = (int *) malloc(N * sizeof(int));
   mat_res[i] = (int *) malloc(Y * sizeof(int));
  }
  
  for(i = 0; i < N; i++)
  mat2[i] = (int *) malloc(Y * sizeof(int));
  /*--------------------------------------------------------------------------------*/
  
  for(i = 0; i < X; i++)
 {
  for(j = 0; j < N; j++)
  {
   mat1[i][j] = 1; 
  }
 }
 
 for(i = 0; i < N; i++)
 {
  for(j = 0; j < Y; j++)
  {
   mat2[i][j] = 2;
  }
 }
 //------------------calculate Start time------------------------
 gettimeofday(&tim, NULL);
 t1 = tim.tv_sec + (tim.tv_usec/1000000.0);
 //--------------------------------------------------------------
 
  for(i = 0; i < X; i++)
  {
   for(j = 0; j < Y;j++)
   {
    sum=0;
    for(k = 0; k < N; k++)
    {
     sum = sum + mat1[i][k] * mat2[k][j];
    }
    mat_res[i][j] = sum;
   }
  }
 //---------------calculate End time-----------------------------
  gettimeofday(&tim, NULL);
 t2 = tim.tv_sec + (tim.tv_usec/1000000.0);
 //--------------------------------------------------------------

 // result = End_time - Start_time
 result = t2 - t1;
  for(i = 0; i < X; i++)
  {
   for(j = 0; j < Y; j++)
   {
    printf("%d\t",mat_res[i][j]);
   }
   printf("\n");
  }
  printf("time taken =%f\n",result);
  return 0;
}

Compile:
gcc matrix_mul_gettimeofday.c -o exec
Run:
./exec

The program matrix_mul_clock_gettime.c given below will show how to calculate time using clock_gettime() function


#include"stdio.h"
#include"time.h"
#include"math.h"
#include"stdlib.h"
#define N 4000
#define X 300
#define Y 200

int main()
{
 int sum = 0,i,j,k;
 int **mat1; //declared mat1[X][N]
 int **mat2; //declare mat2[N][Y]
  int **mat_res; //resultant matrix become mat_res[X][Y]
  struct timespec start,stop;
  double t1=0,t2=0,result=0;
  
  /*----------------------------------------------------*/
 //create array of pointers(Rows)
  mat1 =(int **) malloc(X*sizeof(int*));
  mat2 =(int **)malloc(N*sizeof(int*));
  mat_res=(int **)malloc(X*sizeof(int*));
  /*----------------------------------------------------*/
  
  /*--------------------------------------------------------------------------------*/
 //allocate memory for each Row pointer
  for(i=0; i < X; i++)
  {
   mat1[i]=(int *)malloc(N*sizeof(int));
   mat_res[i]=(int *)malloc(Y*sizeof(int));
  }
  
  for(i = 0; i < N; i++)
  mat2[i]=(int *)malloc(Y*sizeof(int));
  /*--------------------------------------------------------------------------------*/
  
  for(i = 0; i < X; i++)
 {
  for(j = 0; j < N; j++)
  {
   mat1[i][j] = 1; 
  }
 }
 
 for(i = 0; i < N; i++)
 {
  for(j = 0; j < Y; j++)
  {
   mat2[i][j] = 2;
  }
 }
 //------------------calculate Starting time----------------------
 clock_gettime(CLOCK_REALTIME,&start);
 t1 = start.tv_sec + (start.tv_nsec/pow(10,9));
 //--------------------------------------------------------------
 
  for(i = 0; i < X; i++)
  {
   for(j = 0; j < Y;j++)
   {
    sum=0;
    for(k = 0; k < N; k++)
    {
     sum = sum + mat1[i][k] * mat2[k][j];
    }
    mat_res[i][j] = sum;
   }
  }
 //---------------calculate End time-------------------------
  clock_gettime(CLOCK_REALTIME,&stop);
 t2 = stop.tv_sec + (stop.tv_nsec/pow(10,9));
 //--------------------------------------------------------------
 // result = End_time - Start_time
 result = t2 - t1;
  for(i = 0; i < X; i++)
  {
   for(j = 0; j < Y; j++)
   {
    printf("%d\t",mat_res[i][j]);
   }
   printf("\n");
  }
  printf("\ntime taken =\t %lf\n",result);
  return 0;
}
  
In this program CLOCK_REALTIME means choose best wall clock timing of machines which is defined in time.h header file.
compile:
gcc matrix_mul_clock_gettime.c -o exec -lm
Run:
./exec
    Read More...

    Tuesday 15 October 2013

    Matrix Multiplication in MPI

    1 comment
             Message Passing Interface (MPI) is used for distributed computing. MPI is not a language it is library used to fork multiple processes and communicate between them using efficient protocols. MPI has many distributions such as MPICH, MVAPICH, OpenMPI etc.
             The program below explains simple matrix multiplication using point to point communication in MPI.
             Let's consider matrix1 with 5x4 and another matrix2 with 4x3 dimension after matrix multiplication the resultant matrix become 5x3.Consider we are running this matrix multiplication program for 3 processes then the matrix multiplication is performed as shown in the figure below. We can divide the work by using the for loop as shown below
    for(i = rank; i < X; i = i+size)
    matrix multiplication
    
    #include"stdio.h"
    #include"stdlib.h"
    #include"mpi.h"
    #define N 4000
    #define X 300
    #define Y 200
    int main(int argc , char **argv)
    {
     int size,rank,sum=0,i,j,k;
     int **matrix1;  //declared matrix1[X][N]
     int **matrix2; //declare matrix2[N][Y]
      int **mat_res; //resultant matrix become mat_res[X][Y]
      double t1,t2,result;
     MPI_Status status;
     
     MPI_Init(&argc, &argv);
     MPI_Comm_size(MPI_COMM_WORLD, &size);
     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     
     /*----------------------------------------------------*/
     //create array of pointers(Rows)
     matrix1 =(int **)malloc(X * sizeof(int*));
      matrix2 =(int **)malloc(N * sizeof(int*));
      mat_res=(int **)malloc(X * sizeof(int*));
     /*----------------------------------------------------*/
     
     
     /*--------------------------------------------------------------------------------*/
     //allocate memory for each Row pointer
     for(i = 0; i < X; i++)
      {
       matrix1[i]=(int *)malloc(N * sizeof(int));
       mat_res[i]=(int *)malloc(Y * sizeof(int));
      }
      
      for(i = 0; i < N; i++)
      matrix2[i]=(int *)malloc(Y*sizeof(int));
     /*--------------------------------------------------------------------------------*/
     
     for(i = 0; i < X; i++)
     {
      for(j = 0; j < N; j++)
      {
       matrix1[i][j] = 1; //initialize 1 to matrix1 for all processes
      }
     }
     
     for(i = 0; i < N; i++)
     {
      for(j = 0; j < Y; j++)
      {
       matrix2[i][j] = 2;//initialize 2 to matrix2 for all processes
      }
     }
     MPI_Barrier(MPI_COMM_WORLD);
     if(rank == 0)
     t1=MPI_Wtime();
     for(i = rank; i < X; i = i+size) //divide the task in multiple processes
     {
      for(j = 0; j < Y; j++)
      {
       sum=0;
       for(k = 0; k < N; k++)
       {
        sum = sum + matrix1[i][k] * matrix2[k][j];
       }
       mat_res[i][j] = sum;
      }
     }
     
     if(rank != 0)
     {
      for(i = rank; i < X; i = i+size)
      MPI_Send(&mat_res[i][0], Y, MPI_INT, 0, 10+i, MPI_COMM_WORLD);//send calculated rows to process with rank 0
     }
     
     if(rank == 0)
     {
      for(j = 1; j < size; j++)
      {
       for(i = j; i < X; i = i+size)
       {
        MPI_Recv(&mat_res[i][0], Y, MPI_INT, j, 10+i, MPI_COMM_WORLD, &status);//receive calculated rows from respective process
       }
      }
     }
     MPI_Barrier(MPI_COMM_WORLD);
     if(rank == 0)
     t2 = MPI_Wtime();
     result = t2 - t1;
     if(rank == 0)
     {
      for(i = 0; i < X; i++)
      {
       for(j = 0; j < Y; j++)
       {
        printf("%d\t",mat_res[i][j]); //print the result
       }
       printf("\n");
          }
     }
     if(rank == 0)
     printf("Time taken = %f seconds\n",result); //time taken
     MPI_Finalize();
     return 0;
    }
    
    
    Compile:
    mpicc matrix_mul.c -o mul  

    Execute:
    mpirun -np 2 ./mul

    Output:

    MPI Execution

    Explanation:  
            Since we are running MPI program on two cores there may be performance gain than sequential code. You can check this difference in sequential and this parallel multiplication by executing mat_mpi_mul.c and mat_seq.c programs for same large dataset(large matrices), for small dataset(matrices with few rows and column) the result for sequential may be efficient due to overhead of creating processes and message transmission.
           The table below shows the time taken by sequential and parallel matrix multiplication of 3000x4000 and 4000x2000 with different number of processes on quad core Intel i7 machine with MPICH2 library.

    Matrix Multiplication

    Read More...

    Monday 14 October 2013

    Demonstrate Dispatcher Worker model using pthread

    Leave a Comment
            Dispatcher Worker model also called as Boss worker model. In this model there is a server process which contain one dispatcher or boss thread and multiple worker threads. Dispatcher thread continuously check the status of the worker threads and assign job to the thread which is free or idle. Working of this model can be shown in the figure shown below.
    Dispatcher Worker Model

            Here, we are going to demonstrate the working of dispatcher worker model in pthread which is also called as posix thread. As shown in the figure above we are going to create 4 worker threads using pthread_create function and 1 main thread is going to act as dispatcher thread which assigns the job. In the pthread example explain below we are going to consider that there are three jobs with name job1(), job2() and job3(), which are working for 40 seconds which is sufficient time for user to assign job to other threads while one or two are threads are working which is helpful for testing purpose, here you can add your own code. Here we are assigning job when main thread gives signal to worker threads this can be done using pthread_cond_wait() and pthread_cond_signal() functions for details you can visit here.
           As explain above, example of pthread program dispatcher_worker.c is shown below.
    You can compile this program using command below
    gcc dispatcher_worker.c -lpthread
    You can run this program using command below
    ./a.out

    #include"stdio.h"
    #include
    #include
    #include 
    pthread_t th1, th2, th3, th4;
    pthread_cond_t con0 = PTHREAD_COND_INITIALIZER;
    pthread_cond_t con1 = PTHREAD_COND_INITIALIZER;
    pthread_cond_t con2 = PTHREAD_COND_INITIALIZER;
    pthread_cond_t con3 = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER;
    int jobs[4];   //shared array used to submit job
    void *fun1 (void *);
    void *fun2 (void *);
    void *fun3 (void *);
    
    int job1 (int x)
    {
     printf ("This is job1 from thread %d\n", x);
     sleep (40);   //working for 10 seconds 
     //(Suffient time to submit jobs to other threads for testing purpose)
     return 0;
    }
    
    int job2 (int x)
    {
     printf ("This is job2 from thread %d\n", x);
     sleep (40);   //working for 10 seconds 
     //(Suffient time to submit jobs to other threads for testing purpose)
     return 0;
    }
    
    int job3 (int x)
    {
     printf ("This is job3 from thread %d\n", x);
     sleep (40);   //working for 10 seconds 
     //(Suffient time to submit jobs to other threads for testing purpose)
     return 0;
    }
    
    void * fun0 (void *arg)
    {
     int busy = 0;
     int j = 1;
     pthread_mutex_lock (&mutex);
     while (1)
     {
      pthread_cond_wait (&con0, &mutex); //waiting for job to be submitted
      if (jobs[0] == 1)
      {
       job1 (busy);
       jobs[0] = 0;
      }
      else if (jobs[0] == 2)
      {
       job2 (busy);
       jobs[0] = 0;
      }
      else if (jobs[0] == 3)
      {
       job3 (busy);
       jobs[0] = 0;
      }
      else
      {   //do nothing
      }
     }
     pthread_mutex_unlock (&mutex);
    }
    
    void * fun1 (void *arg)
    {
     int busy = 1;
     pthread_mutex_lock (&mutex2);
     while (1)
     {
      pthread_cond_wait (&con1, &mutex2); //waiting for job to be submitted
      if (jobs[1] == 1)
      {
       job1 (busy);  //pass the thread number
       jobs[1] = 0;
      }
      else if (jobs[1] == 2)
      {
       job2 (busy);
       jobs[1] = 0;
      }
      else if (jobs[1] == 3)
      {
       job3 (busy);
       jobs[1] = 0;
      }
      else
      {   //do nothing
      }
     }
     pthread_mutex_unlock (&mutex2);
    }
    
    void *
    fun2 (void *arg)
    {
     int busy = 2;
     pthread_mutex_lock (&mutex3);
     while (1)   //going to infinite state 
     {
      pthread_cond_wait (&con2, &mutex3); //waiting for job to be submitted
      if (jobs[2] == 1)
      {
       job1 (busy);
       jobs[2] = 0;
      }
      else if (jobs[2] == 2)
      {
       job2 (busy);
       jobs[2] = 0;
      }
      else if (jobs[2] == 3)
      {
       job3 (busy);
       jobs[2] = 0;
      }
      else
      {   //do nothing
      }
     }
     pthread_mutex_unlock (&mutex3);
    }
    
    void * fun3 (void *arg)
    {
     int busy = 3;
     pthread_mutex_lock (&mutex4);
     while (1)
     {
      pthread_cond_wait (&con3, &mutex4); //waiting for job to be submitted
      if (jobs[3] == 1)
      {
       job1 (busy);
       jobs[3] = 0;
      }
      else if (jobs[3] == 2)
      {
       job2 (busy);
       jobs[3] = 0;
      }
      else if (jobs[3] == 3)
      {
       job3 (busy);
       jobs[3] = 0;
      }
      else
      {   //do nothing
      }
     }
     pthread_mutex_unlock (&mutex4);
    }
    
    int main ()
    {
     int i, j, k = 0, job_no = 0, th_no = 0;
     char choice, cond_var[20];
     for (i = 0; i < 4; i++)
     jobs[i] = 0;
     pthread_create (&th1, NULL, fun0, NULL);
     pthread_create (&th2, NULL, fun1, NULL);
     pthread_create (&th3, NULL, fun2, NULL);
     pthread_create (&th4, NULL, fun3, NULL);
     while (1)
     {
      k = 0;
      //printf ("Assign job to the free threads given below\n");
      for (i = 0; i < 4; i++)
      {
       if (jobs[i] == 0)
       {
        printf ("%d\t", i);
        k++;
       }
      }
    
      if (k > 0)
      {
       printf("numbered threads are free\n");
       printf("-------------------------------------------------------");
       printf ("\nWant to give job Y:yes N:no T:\"Terminate\" \n");
       scanf ("%s", &choice);
       if (choice == 'Y' || choice == 'y')
       {
        printf ("Enter job number (1-3) and thread number (0-3)\n");
        scanf ("%d %d", &job_no, &th_no);
        if (th_no == 0)
        {
         pthread_mutex_lock (&mutex);
         jobs[th_no] = job_no;
         pthread_cond_signal (&con0); //wake up thread waiting for condition variable con0
         pthread_mutex_unlock (&mutex);
        }
        else if (th_no == 1)
        {
         pthread_mutex_lock (&mutex2);
         jobs[th_no] = job_no;
         pthread_cond_signal (&con1); //wake up thread waiting for condition variable con1
         pthread_mutex_unlock (&mutex2);
        }
        else if (th_no == 2)
        {
         pthread_mutex_lock (&mutex3);
         jobs[th_no] = job_no;
         pthread_cond_signal (&con2); //wake up thread waiting for condition variable con2
         pthread_mutex_unlock (&mutex3);
        }
        else if (th_no == 3)
        {
         pthread_mutex_lock (&mutex4);
         jobs[th_no] = job_no;
         pthread_cond_signal (&con3); //wake up thread waiting for condition variable con3
         pthread_mutex_unlock (&mutex4);
        }
        else
        {
        }
       }
       else if (choice == 'T' || choice == 't')
       {
        exit (0);
       }
       else
       {
       }
      }
      else if (k == 0)
      {
       printf ("All threads are busy\n");
       sleep (2);
      }
      else
      {   //do nothing
      }
     }
    
     pthread_join (th1, NULL);
     pthread_join (th2, NULL);
     pthread_join (th3, NULL);
     pthread_join (th4, NULL);
     return 0;
    }
    
    Output:

          Since multiple threads are running parallel the sequence of output (that is printing) of statements may get vary. As shown in the figure above line number 12 is the output of previously given job to thread number 0, but output of this statement is appearing after line number 11 which is the output line of main thread. So you the program is waiting for input at line number 13 not at 12.
    Read More...

    Friday 11 October 2013

    Apache Thrift Tutorial

    1 comment

    Introduction

           Apache thrift is a tool developed at Facebook which is used for automatically creating remote servers in Remote Procedure Call (RPC) in different languages. Thrift means economical, since it is saving time and cost for creating remote servers in RPC.  Apache thrift support many different languages . Apache thrift won't create client, you require to create the client program manually. Apache thrift is an Interface Definition language (IDL) used to create services in a different language.

    Installation 

    On Ubuntu:
           You can install all dependencies by giving only one single command as shown below
    sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev 

    OR

           If there is an error in above command please check due to which dependency error is occurring.
    • First check whether your g++ version is greater or equal to 4.2 you may check the version with the command given below
      g++ --version   (This should be >= 4.2)
    • Install lex and yacc using command given below
      sudo apt-get install byacc flex
    • Install boost library using command given below
      sudo apt-get install libboost-all-dev
    • Install autoconf which is require for building the source
      sudo apt-get install autoconf
    • Install  automake
      sudo apt-get install automake
    • Install libtool
      sudo apt-get install libtool
    • install libssl-dev
       sudo apt-get install libssl-dev
    • Install pkg-config
      sudo apt-get install pkg-config
    • Install libevent-dev
      sudo apt-get install libevent-dev
    • Install bison
      sudo apt-get install bison

           Now download the apache thrift and extract it. After extracting open terminal and go to the path where thrift is extracted and give the following commands
    ./configure
    make
    sudo make install
           You can check whether apache thrift is installed properly or not by giving command below. If you are able to see the version of thrift then your installation is completed successful.
    thrift --version

    Use

          As explain before we can create source codes for many languages without installation of that language, but to run created source code you will require to install those language. To create remote server you will require to create a file with extension thrift. This thrift file contain thrift interface description language we will explain this in short for detail refer link.

    Lets create one example which performs basic arithmetic operations Thrift_IDL.thrift.

    #this is comment
    #!/usr/local/bin/thrift --gen cpp
    
    namespace cpp Test #this indicates that given thrift is applicable to cpp 
    
    service arithmetic_op  #create class arithmetic_opHandler : virtual public arithmetic_opIf with following public function
    {       
      i32 add(1:i32 num1, 2:i32 num2),  #this create function with int32_t add(const int32_t num1, const int32_t num2)
      i32 sub(1:i32 num1, 2:i32 num2),  #this create function with int32_t sub(const int32_t num1, const int32_t num2) 
      i32 mul(1:i32 num1, 2:i32 num2),  #this create function with int32_t mul(const int32_t num1, const int32_t num2) 
      i32 div(1:i32 num1, 2:i32 num2),  #this create function with int32_t div(const int32_t num1, const int32_t num2)
    }
    
    service arithmetic_Demo      #this is second service for dispay
    {
    i32 display(1:i32 num1, 2:i32 num2)
    }
    To generate server for this file you require to give the command
    thrift --gen cpp Thrift_IDL.thrift
           This command will generate one folder with name "gen-cpp" which contain 10 files as shown in the figure below. This number of file and the format of files changes as the language changes, here we are considering the files for cpp.
    Apache Thrift
      
           Since we don't define any struct or enum declared in thrift file, the file Thrift_IDL_types.h, Thrift_IDL_types.cpp are only initialized but not used.

    Modify Functions declared in Services(.thrift file):
           Functions declared in the services of thrift file are only initialized by thrift. You require to add the contain to perform some action you require.
           We will take example of arithmetic_op service: thrift will create arithmetic_op_server.skeleton.cpp file which contain main function and thrift will create arithmetic_opHandler class which contain constructor and the number of functions declared in the thrift file as shown below.
    class arithmetic_opHandler : virtual public arithmetic_opIf {
     public:
      arithmetic_opHandler() {
        // Your initialization goes here
      }
    
      int32_t add(const int32_t num1, const int32_t num2) {
        // Your implementation goes here
        printf("add\n");
      }
    
      int32_t sub(const int32_t num1, const int32_t num2) {
        // Your implementation goes here
        printf("sub\n");
      }
    
      int32_t mul(const int32_t num1, const int32_t num2) {
        // Your implementation goes here
        printf("mul\n");
      }
    
      int32_t div(const int32_t num1, const int32_t num2) {
        // Your implementation goes here
        printf("div\n");
      }
    };
    
            You can add logic of addition, subtraction, multiplication and division in the functions add(), sub(), mul(), div() respectively. This functions are taking two inputs from client and printing the function name, instead of this you can add the logic of arithmetic operation.
    Compiling:
    • g++ -I/usr/local/include/thrift -c arithmetic_Demo.cpp
    • g++ -I/usr/local/include/thrift -c arithmetic_Demo_server.skeleton.cpp
    • g++ -I/usr/local/include/thrift -c arithmetic_op.cpp
    • g++ -I/usr/local/include/thrift -c arithmetic_op_server.skeleton.cpp
    • g++ -I/usr/local/include/thrift -c Thrift_IDL_constants.cpp
    • g++ -I/usr/local/include/thrift -c Thrift_IDL_types.cpp
    To compile all files in one stroke you can use the command given below
    g++ -I/usr/local/include/thrift -c *.cpp
    Here *cpp represent all files with extension .cpp.
    Explanation:
          -I: option which is used by gcc compiler to locate the header files. In this compilation we are suggesting the gcc compiler to search for the header files in the "/usr/local/include/thrift/" folder also.
          Since it is only compilation gcc compiler won't link the thrift libraries which eliminates the requirement of including thrift library with -lthrift.
          -c: option in gcc compiler is used to create object files if you don't provide -o followed by your custom name of object file it will create object file with the same name of your c or cpp file with .o extension.

    Linking:
           Since there are two services in our example we get two Service_name_server_skeleton.cpp files which contain main function in it. Due to this we require to link this two service_skeleton.cpp files separately, which will create two executables with two different service.
           You can use the command given below for linking the services

    Link "arithmetic_op" service:
     
    g++ -L/usr/local/lib/ arithmetic_op.o arithmetic_op_server.skeleton.o Thrift_IDL_constants.o Thrift_IDL_types.o -lthrift -o arithmetic_op

    Link "arithmetic_Demo" service:

    g++ -L/usr/local/lib/ arithmetic_Demo.o arithmetic_Demo_server.skeleton.o Thrift_IDL_constants.o Thrift_IDL_types.o -lthrift -o arithmetic_Demo

    Explanation:
    -L: This option is used when you want compiler to link with libraries present in directory other than LD_LIBRARY_PATH environment variable. Here we have used to link with thrift library named "libthrift.a" or "libthrift.so". Here .a represent static library where as .so represent dynamic library.

    -o: This option is used to give custom name to your executable by default it is a.out
    Read More...