| 
 void *worker (void *arg)
 {
     ....
     (You will need to convert arg to the
     correct type before you can use the value passed)
     ....
 }
 int main(int argc, char *argv[])
 {
    // SEQUENTIAL Section 
    .... Prepare problem (setup shared variables) ....
    // PARALLEL Section 
    // Start the worker threads
    for (i = 0; i < NUM_PROCESSORS; i = i + 1)
    {
       param[i] = ....;
       pthread_create(&tid[i], &attr, worker, & param[i])           
    }
    // Wait for all workers to finish
    for (i = 0; i < NUM_PROCESSORS; i = i + 1)
        pthread_join(tid[i], NULL);
    // SEQUENTIAL Section 
    .... Post process results from workers....
    (Or start another prepare section followed by a parallel + join section)    
 }
 | 
Note:
| 
 | 
| 
 | 
| 
 | 
because:
|   | 
You will see in the demo programs that the data that need to be processed are stored in a global variabel
You do this, so that:
| 
 | 
| 
 | 
(And sometimes, it is not possible to divide the task into non-overlapping tasks and you may have to repeat some steps - necessary evil in parallel programming...
Some ways are better than others.
Pictorially:
| 
      values handled by        values handled by
         thread 0                  thread 1
   |<--------------------->|<--------------------->|     
              |                        |
              |                        |
              V                        V
            min[0]                  min[1]
               \                      /
                \                    /
                 \                  /
                  \                /
                   \              /
		      main thread
			   |
			   |
			   V
		      Actual minimum
 | 
In general, the division of the data in the array is as follows
|   | 
Main Thread:
| 
 | 
C++ code for the main( ) function:
| 
   /* Shared Variables */
   double x[1000000];   // Must be SHARED (accessed by worker threads !!) 
   int    start[100];   // Contain starting array index of each thread
   double min[100];     // Contain the minimum found by each thread
   int    num_threads;
   // -----------------------------------
   // Create worker threads....
   // -----------------------------------
   for (i = 0; i < num_threads; i = i + 1)
   {
      start[i] = i;     // Pass ID to thread in a private variable
      if ( pthread_create(&tid[i], NULL, worker, (void *)&start[i]) )
      {
         cout << "Cannot create thread" << endl;
         exit(1);
      }
   }
   // -----------------------------------
   // Wait for worker threads to end....
   // -----------------------------------
   for (i = 0; i < num_threads; i = i + 1)
      pthread_join(tid[i], NULL);
   // ----------------------------------------
   // Post processing: Find actual minimum
   // ----------------------------------------
   my_min = min[0];
   for (i = 1; i < num_threads; i++)
      if ( min[i] < my_min )
         my_min = min[i];
 | 
Worker Thread:
| 
 | 
The C++ code for worker( ):
| 
  void *worker(void *arg)
  {
     int i, s;
     int n, start, stop;
     double my_min;
  
     n = MAX/num_threads;	// number of elements to handle    
  
     s = * (int *) arg;         // Convert arg to an integer 
  
     start = s * n;		// Starting index
  
     if ( s != (num_threads-1) )
     {
        stop = start + n;	// Ending index
     }
     else
     {
        stop = MAX;
     }
  
     my_min = x[start];
  
     for (i = start+1; i < stop; i++ )    // Find min in my range
     {
        if ( x[i] < my_min )
           my_min = x[i];
     }
  
     min[s] = my_min;			  // Store min in private slot   
     return(NULL);     /* Thread exits (dies) */
  }
 | 
 
        
   
  On Solaris compile with: CC -mt min-mt1.C
  
  On Linux compile with: g++ -pthread  min-mt1.C
Changes that you need to make to compile on Linux:
    #include <iostream.h>   ===>   #include <iostream>
    Add line:  using namespace std;
 
Pictorially:
| 
                values handled by thread 0
   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   V   V   V   V   V   V   V   V   V   V   V   V   V   V
   |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|      
     ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^
     |   |   |   |   |   |   |   |   |   |   |   |   |   |
                values handled by thread 1
          Thread 0                Thread 1
              |                        |
              |                        |
              V                        V
            min[0]                  min[1]
               \                      /
                \                    /
                 \                  /
                  \                /
                   \              /
		      main thread
			   |
			   |
			   V
		      Actual minimum
 | 
|   | 
Main Thread: (UNCHANGED)
| 
   // -----------------------------------
   // Create worker threads....
   // -----------------------------------
   for (i = 0; i < num_threads; i = i + 1)
   {
      start[i] = i;     // Pass ID to thread in a private variable
      if ( pthread_create(&tid[i], NULL, worker, (void *)&start[i]) )
      {
         cout << "Cannot create thread" << endl;
         exit(1);
      }
   }
   // -----------------------------------
   // Wait for worker threads to end....
   // -----------------------------------
   for (i = 0; i < num_threads; i = i + 1)
      pthread_join(tid[i], NULL);
   // ----------------------------------------
   // Post processing: Find actual minimum
   // ----------------------------------------
   my_min = min[0];
   for (i = 1; i < num_threads; i++)
      if ( min[i] < my_min )
         my_min = min[i];
 | 
Worker Thread: (CHANGED !!!)
| 
  void *worker(void *arg)
  {
     int i, s;
     double my_min;
  
     s = * (int *) arg;       // Convert arg to an integer
  
     // --------------------------------------
     // Find min in my range
     // --------------------------------------
     my_min = x[s];
  
     for (i = s+num_threads; i < MAX; i += num_threads)      
     {
        if ( x[i] < my_min )
           my_min = x[i];
     }
  min[s] = my_min; 		// Store min in private slot 
     return(NULL);     /* Thread exits (dies) */
  } | 
See the elements processed by the thread s:
|   | 
It's much easier to code the worker thread !!!
 
        
   
Compile with: g++ -pthread min-mt2.C
But the second version... no so much...
Each thread traverse the array from the beginning until the end.
Due to the large size of the array, the whole array cannot be stored in memory and will be paged in when a thread access the desired array elements.
(Solution 1 does not have the page problem, because the array element access pattern is "limited" to a tightly coupled region of the array)