Share Pastebin
Guest
Public paste!

Untitled

By: a guest | Mar 22nd, 2010 | Syntax: C++ | Size: 5.14 KB | Hits: 109 | Expires: Never
Copy text to clipboard
  1. // A program that spell checks works in parallel
  2. // By Mike Solomon for Parallel Programming
  3. // Program 2
  4. // 3-18-10
  5.  
  6. #include <fstream>
  7. #include <iostream>
  8. #include <pthread.h>
  9. #include <stdlib.h>
  10. #include <string>
  11. #include <vector>
  12.  
  13. using namespace std;
  14.  
  15. typedef struct
  16. {
  17.         string * data_ptr;
  18.         int order;
  19. }THREAD_ARG_T;
  20.  
  21.  
  22. void *spellCheck ( void * arg )
  23. {
  24.         // Cast arg to a pointer of THREAD_ARG_T
  25.         THREAD_ARG_T *arg_pointer = static_cast<THREAD_ARG_T *>(arg);
  26.        
  27.         // Get the input stored in arg pointer
  28.         string * data_ptr = arg_pointer -> data_ptr;
  29.  
  30.         // Dereference it so I don't have to use *input
  31.         // throughout my program
  32.         string & data = *data_ptr;
  33.  
  34.         // Get the ordering of it
  35.         int order = arg_pointer -> order;
  36.  
  37.         cout << "Thread " << pthread_self() << " stopping by to say hi!"
  38.                 << endl;
  39.         cout << "My data = " << data << endl;
  40.         cout << "My order = " << order << endl;
  41.  
  42.         return NULL;
  43. }
  44.  
  45. int main (int argc, char *argv[])
  46. {
  47.         // inData is like cin
  48.         ifstream inData;
  49.  
  50.         // Gets the number of threads
  51.         int numThreads = atoi(argv[1]);
  52.  
  53.         // Temporary string to store reading in data
  54.         string tempString = "";
  55.  
  56.         // An array of strings for all the input data
  57.         //vector<string> input;
  58.         vector<THREAD_ARG_T *> input;
  59.  
  60.         // Opens the file for us to read
  61.         inData.open(argv[2]);
  62.  
  63.         // File couldn't be opened
  64.         if ( !inData )
  65.         {
  66.                 cerr << "Error: file could not be opened" << endl;
  67.                 exit(1);
  68.         }
  69.  
  70.         // Used to keep track of the order of the items
  71.         int count = 0;
  72.  
  73.         // While there is still data in the file
  74.         while ( !inData.eof() )
  75.         {
  76.                 // Get the next line from indata and
  77.                 // store it in tempString
  78.                 getline( inData, tempString );
  79.        
  80.                 // Create a thread_arg_t to add to our vector
  81.                 THREAD_ARG_T * data = new THREAD_ARG_T;
  82.        
  83.                 // Set the pointer to the address of this string
  84.                 (*data).data_ptr = &tempString;
  85.                
  86.                 // Set it's ordinal value
  87.                 (*data).order = count;
  88.  
  89.                 // Incremenet the count
  90.                 count++;
  91.  
  92.                 // Push it onto our array
  93.                 input.push_back(data);
  94.         }
  95.        
  96. //      THREAD_ARG_T x = *input.at(0);
  97.  
  98. //      cout << "x.data_ptr = " << x.data_ptr << endl;
  99.  
  100.         // This is slightly complex. As count is incremented
  101.         // after each loop we end up with count being one
  102.         // greater than the position of the last element.
  103.         // Furthermore, we subtract another one because
  104.         // the last element is the empty string as C++
  105.         // seems to read data in like that.
  106.         // In other words, this is the position of the
  107.         // last element that we care about.
  108.         count = count - 2;
  109.  
  110.         // If the number of threads is greater than the
  111.         // number of strings then we shouldn't really
  112.         // use that number of threads.
  113.         if ( numThreads > count )
  114.         {
  115.                 numThreads = count;
  116.         }
  117.  
  118.         // Push it onto the end of the vector
  119.         //input.pop_back();
  120.  
  121.         // Close the input stream
  122.         inData.close();
  123.  
  124.         // Store the thread pointers in an array of pthread_t*
  125.         // elements.
  126.         //
  127.         // The type of my_thread is pthread_t**, because we
  128.         // are creating an array of pointeres.
  129.         pthread_t **my_thread = new pthread_t*[numThreads];
  130.  
  131.         // The pointers don't point to anything. Lets fix
  132.         // that and allocate a pthread_t for each thread
  133.         // and then make the pointers point to them.
  134.         for (int i = 0; i < numThreads; i++)
  135.         {
  136.                 my_thread[i] = new pthread_t;
  137.         }
  138.  
  139.         //vector <THREAD_ARG_T> arguments;
  140.         //int argCount = 0;
  141.  
  142.         // Create the threads themselves (i.e. initialize
  143.         // the threads that we just made).
  144.         for (int i = 0; i < numThreads; i++)
  145.         {
  146.                 // Get the argument we're going to have this thread
  147.                 // point towards.
  148.                 //THREAD_ARG_T argument;
  149.                
  150.                 //cout << "Attempting to grab data: " << *input.at(count).data_ptr <<
  151.                 //" and order = " << count << endl;
  152.  
  153.                 // Pass in the information to the argument
  154.                 //argument.data_ptr = input.at(count).data_ptr;
  155.                 //argument.order = input.at(count).order;
  156.  
  157.                 // Decrement so we go to the previous term
  158.                 //count--;
  159.  
  160.                 // Add this argument to our vector of arguments
  161.                 //arguments.push_back(argument);
  162.  
  163.                 // Creater a pointer to the arguments
  164.                 THREAD_ARG_T *arg_ptr = input.at(count);
  165.                 count--;
  166.  
  167.                 // ... and convert it to the proper type
  168.                 void *converted_arg_ptr = static_cast<void *>(arg_ptr);
  169.  
  170.                 // Create the thread
  171.                 if (pthread_create (my_thread[i],
  172.                                     NULL,
  173.                                     spellCheck,
  174.                                     converted_arg_ptr))
  175.                 {
  176.                         cout << "Error creating thread " <<
  177.                                 i << '.' << endl;
  178.                         abort();
  179.                 }
  180.                
  181.                 // Increment the argCounter
  182.                 //argCount++;
  183.         }
  184.        
  185.         // Joing them all together
  186.         for (int i = 0; i < numThreads; i++)
  187.         {
  188.                 // pthread_join takes a static pthread_t,
  189.                 // not a pointer to a pthread t.
  190.                 // Since my_thread[i] is a pthread_t *, we
  191.                 // need to dereference it to get a pthread_t.
  192.                 if (pthread_join (*my_thread[i], NULL) )
  193.                 {
  194.                         cout << "Error joining thread." << endl;
  195.                         abort();
  196.                 }
  197.         }
  198.  
  199.         // Clean up. Since we dynamically allocated each thread,
  200.         // we need to deallocate it. But, don't deallocate a thread
  201.         // that hasn't exited! Here we know that each thread has
  202.         // exited from the pthread_join() call above.
  203.         for (int i = 0; i < numThreads; i++)
  204.         {
  205.                 delete my_thread[i];
  206.         }
  207.  
  208.         // Finally, deallocate the array of pthread_t pointers.
  209.         delete [] my_thread;
  210.  
  211.         exit(0);
  212. }