I am working on a project that simulates client requests and runs a process from a different file (this process was given to me, so I'm not supposed to edit it).
I have to use the producer-consumer method for this problem and use semaphores and a mutex lock to ensure no deadlocking, etc. I am running into the issue that my threads don't seem to realize when there is a connection and aren't triggered to complete the jobs on the server. The program creates the threads successfully, but I think I'm just missing something or not understanding the basics of how all the things I mentioned above work together. I want to understand the logic of what triggers a thread to begin working and how that makes sense with a listener / socket system waiting on a client connection. Here is a breakdown of the code, I don't want to include all of it, just the frameworks of how it all works.
#define MAX_REQUEST 100
int port, numThread;
typedef int bufferItem;
bufferItem buffer[MAX_REQUEST]; // shared buffer
int bufferIndex;
bool connection = false;
pthread_t threads[MAX_REQUEST];
sem_t full;
sem_t empty;
pthread_mutex_t mutex;
int insertItem(bufferItem item) {
// This method adds the item in the argument to the buffer and increments the buffer index.
if(bufferIndex < MAX_REQUEST) {
buffer[bufferIndex] = item;
bufferIndex++;
return(0); // success
}
else {
return(-1); // error
}
}
int removeItem() {
bufferItem item;
if(bufferIndex > 0) {
bufferIndex--;
item = buffer[bufferIndex];
process(item); // run process (outside method) HERE
return(0); // success
}
else {
return(-1); // error
}
}
int req_handler() {
// this method opens a socket and starts HTTP server listening on port
// after connection to client is successful, following code executes
while (1) {
int s;
s = accept(sock, NULL, NULL);
if (s < 0) break;
bool connection = true;
printf("Connected!\n");
//put in request for info (file descriptor) into shared buffer
insertItem(s);
sem_post(&empty); // I think I may have an error here, I have tried different things to trigger the thread but nothing works
}
// socket is closed
}
void *producer (void *arg) {
// tests if there is a connection using a boolean
// decrements buffer with empty semaphore
// locks mutex
int ret = insertItem(gettid()); // put item in buffer
// unlocks mutex so other threads can use
// increments buffer with full semaphore
}
void *consumer (void *arg) {
// tests if there is a connection using a boolean
// decrements full semaphore
// locks mutex
int ret = removeItem(); // put item in buffer
// unlocks mutex
// increments buffer with empty semaphore
}
int main(int argc, char *argv[]) {
// sets up command line arguments to get port number and number of threads
// initializes semaphores and mutex
pthread_mutex_init(&mutex, NULL);
sem_init(&empty, 0, MAX_REQUEST);
sem_init(&full, 0, 0);
int threadNum[numThread]; // keep track of threads
for (i = 0; i < numThread; i++) { // create threads
threadNum[i] = i;
if (i == 0) {
if(pthread_create(&threads[i], NULL, producer, (void *)&threadNum[i]) != 0) {
perror("Producer: Thread creation error");
}
} else {
if(pthread_create(&threads[i], NULL, consumer, (void *)&threadNum[i]) != 0) {
perror("Consumer: Thread creation error");
}
}
printf("Main: Thread Created :)\n");
}
// wait until all threads have exited (joined)
for(i = 0; i < numThread; i++) {
printf("Main: Thread Joined with numThread: %d and i %d \n",numThread,i);
if(pthread_join(threads[i], NULL) != 0) {
perror("Main: Thread join error");
}
}
req_handler(); // starts listener
printf("All threads joined, destrying semaphores and mutex :)\n");
// destroys semaphores and mutexes
return 0;
}
emptyfullfull