Don't mind the commenting of code, I just switched my implementation around so that's why a lot of things are commented out. My problem lies in the "quitting" of the program. The program reads from standard input until the letter 'q' or 'Q' (upper or lower case) is entered, than quits and signals the other threads to shut down. It technically works because I get a segmentation fault ...but in the real world that doesn't count. Can anyone have a look and help me figure out whats wrong, i've tried debugging with no luck (not sure how to do it with threads in gdb). But anyways, so program runs fine until command 'Q' or 'q' is entered, than exits due to segmentation fault. Thanks in advance. The only thing I can think of is probably the way i'm shutting down the threads...
Code:
// To compile: gcc -lpthread -lrt program.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
//Definitions
#define NOTSHARED 0
#define BUFFSIZE 81
//Type
typedef enum { FALSE, TRUE } boolean;
//Function prototypes
void *inputFcn( void *id );
void *processFcn( void *id );
void *outputFcn( void *id );
//Globals (shared data)
char *operator1;
int operand1, operand2, result;
boolean quit = FALSE;
//mutex's
//pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
//pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
// the semaphores used to coordinate thread activity
sem_t semaphore1, semaphore2, semaphore3;
int main( int argc, char *argv[] )
{
pthread_t input, process, output;
// Since mutex are initially unlocked, we lock them...
//pthread_mutex_lock( &mutex1 );
//pthread_mutex_lock( &mutex2 );
//pthread_mutex_lock( &mutex3 );
// initialize the semaphores
sem_init( &semaphore1, NOTSHARED, 0 );
sem_init( &semaphore2, NOTSHARED, 0 );
sem_init( &semaphore3, NOTSHARED, 0 );
// Creating thread...
pthread_create( &input, NULL, inputFcn, NULL );
pthread_create( &process, NULL, processFcn, NULL );
pthread_create( &output, NULL, outputFcn, NULL );
pthread_exit( NULL );
}
void *inputFcn( void *id )
{
char buffer[ BUFFSIZE ]; // room for 80 chars plus \0
char *input;
input = fgets( buffer, BUFFSIZE, stdin );
while( *input != 'q' || *input != 'Q' )// && quit == FALSE ) //&& strstr( input, "q" ) == NULL && strstr( input, "Q" ) == NULL )
{
//Format of string will be error free and
//in the format 'operand operator operand'
//convert operand's to integers
//if( *input == 'q' || *input == 'Q' )//input[0] == 'q' || input[0] == 'Q' )
// quit = TRUE;
operand1 = atoi( strtok( input, " " ) ); //write first operand to shared data
operator1 = strtok( NULL, " " ); //write operator to shared data
operand2 = atoi( strtok( NULL, " " ) ); //write second operand to shared data
//pthread_mutex_unlock( &mutex2 );
//pthread_mutex_lock( &mutex1 );
sem_post( &semaphore2 );
sem_wait( &semaphore1 );
input = fgets( buffer, BUFFSIZE, stdin );
}
quit = TRUE;
pthread_exit( NULL );
}
void *processFcn( void *id )
{
while( quit == FALSE )
{
//pthread_mutex_lock( &mutex2 );
sem_wait( &semaphore2 );
switch ( operator1[0] ) /* select the type of calculation */
{
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
case '%':
result = operand1 % operand2;
break;
default:
printf( "Invalid operator specified!" );
break;
}
//pthread_mutex_unlock( &mutex3 );
sem_post( &semaphore3 );
}//end while
pthread_exit( NULL );
}
void *outputFcn( void *id )
{
while( quit == FALSE )
{
//pthread_mutex_lock( &mutex3 );
sem_wait( &semaphore3 );
printf( "\nResult was %d \n", result );
//pthread_mutex_unlock( &mutex1 );
sem_post( &semaphore1 );
}
pthread_exit( NULL );
}