231 lines
6.3 KiB
C++
231 lines
6.3 KiB
C++
![]() |
/*
|
||
|
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 <cassert>
|
||
|
#include <cstring>
|
||
|
#include <iostream>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <pthread.h>
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#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<int> John_vec(100);
|
||
|
vector<int> Jane_vec(100);
|
||
|
vector<int> 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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|