/* File: simpleclient.C Author: R. Bettati Department of Computer Science Texas A&M University Date : 2013/01/31 Simple client main program for MP3 in CSCE 313 */ /*--------------------------------------------------------------------------*/ /* DEFINES */ /*--------------------------------------------------------------------------*/ /* -- (none) -- */ /*--------------------------------------------------------------------------*/ /* INCLUDES */ /*--------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include "reqchannel.h" #include "semaphore.h" #include "BoundedBuffer.h" using namespace std; /*--------------------------------------------------------------------------*/ /* DATA STRUCTURES */ /*--------------------------------------------------------------------------*/ /* none */ /*--------------------------------------------------------------------------*/ /* CONSTANTS */ /*--------------------------------------------------------------------------*/ BoundedBuffer Request_Buffer; BoundedBuffer Response_Buffer[3]; BoundedBuffer RB1; vector John_vec(100); vector Jane_vec(100); vector Joe_vec(100); int n = 1000, b = 100, w = 5;//set defaults /*--------------------------------------------------------------------------*/ /* FORWARDS */ /*--------------------------------------------------------------------------*/ void* Req_Thread(void* args); void* Worker_Thread(void* args); void* Stat_Thread(void* args); /*--------------------------------------------------------------------------*/ /* MAIN FUNCTION */ /*--------------------------------------------------------------------------*/ int main(int argc, char * argv[]) { int option = -1; while ((option = getopt(argc, argv, "n:b:w:")) != -1){ switch (option){ case 'n' : n = atoi(optarg); break; case 'b' : b = atoi(optarg); break; case 'w' : w = atoi(optarg); break; } } pid_t pid = fork(); if(pid != 0){ Request_Buffer.set_empty(b); Response_Buffer[0].set_empty(b); Response_Buffer[1].set_empty(b); Response_Buffer[2].set_empty(b); RequestChannel chan("control", RequestChannel::CLIENT_SIDE); pthread_t request_thread_ids[3]; pthread_t worker_thread_ids[w]; pthread_t statistic_thread_ids[3]; RequestChannel* worker_return[w]; //--------------------------------------------- //------- pthread_create ------- //--------------------------------------------- int index[3]; for(int i=0; i < 3; i++){ index[i] = i; pthread_create(&request_thread_ids[i], NULL, Req_Thread, (void *)&index[i]); } for(int i=0; i < w; i++){ string channel_name = chan.send_request("newthread"); worker_return[i] = new RequestChannel(channel_name, RequestChannel::CLIENT_SIDE); pthread_create(&worker_thread_ids[i], NULL, Worker_Thread, worker_return[i]); } for(int i=0; i < 3; i++){ pthread_create(&statistic_thread_ids[i], NULL, Stat_Thread, (void *)&i); } //--------------------------------------------- //-------- pthread_join -------- //--------------------------------------------- for(int i=0; i < 3; i++){ pthread_join(request_thread_ids[i], NULL); } for(int i=0; i < w; i++){ pthread_join(worker_thread_ids[i], NULL); } for(int i=0; i < 3; i++){ pthread_join(statistic_thread_ids[i], NULL); } for(int i=0; i < w; i++){ worker_return[i]->send_request("quit"); } cout << "\n\n HISTOGRAM \n"; int ct = 0; for(int i=0; i < 100; i++){ cout << "Num: " << i << "\tTimes: " << John_vec[i] << endl; } //STILL NEED TO OUTPUT THE HISTOGRAM SOMEHOW.... chan.send_request("quit"); }else{ execl("dataserver", 0); } usleep(1000000); } void* Worker_Thread(void* arg){ RequestChannel* chann = (RequestChannel*)arg; while(true){ string request = Request_Buffer.pop(); string response = chann->send_request(request); if(request == "data Joe Smith"){ Response_Buffer[0].push(response); }else if(request == "data Jane Smith"){ Response_Buffer[1].push(response); }else if(request == "data John Doe"){ Response_Buffer[2].push(response); }else if(request == "quit"){ //Break out of the thread if quit response is found break; } } } void* Req_Thread(void* arg){ int person = *(int*)arg; cout << "PERSON: " << person << endl; switch(person){ case 0: for(int i=0; i < n; i++){ Request_Buffer.push("data Joe Smith"); cout << "JOE";} break; case 1: for(int i=0; i < n; i++){ Request_Buffer.push("data Jane Smith"); cout << "JANE";} break; case 2: for(int i=0; i < n; i++){ Request_Buffer.push("data John Doe"); cout << "JOHN";} break; } } void* Stat_Thread(void* arg){ //send to proper response buffer based on which name is found! int person = *(int*)arg; string num; if(person == 0){ for(int i=0; i < n; i++){ num = Response_Buffer[0].pop(); int v = atoi(num.c_str()); John_vec[v] = John_vec[v] + 1; } }else if(person == 1){ for(int i=0; i < n; i++){ num = Response_Buffer[1].pop(); cout << "\nPERSON1: " << num << endl; int v = atoi(num.c_str()); Jane_vec[v] = Jane_vec[v] + 1; } }else if(person == 2){ for(int i=0; i < n; i++){ num = Response_Buffer[2].pop(); int v = atoi(num.c_str()); John_vec[v] = John_vec[v] + 1; } } }