C中的Pthread等待问题

时间:2015-03-26 08:31:52

标签: c multithreading posix

嘿伙计们我的pthreads遇到了一些麻烦。我不断得到一个段错误,我相信当我让我的线程等待时。我希望有人可以看看,看看我哪里出错了。

快速概述应该发生的事情。我正在将文件一次读入缓冲区1000个字符,我应该使用POSIX线程计算其中的行数。我必须通过锁定,解锁,等待和信令来实现它。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>

/**Structs**/
typedef struct BufferElement {

    int blockLength;
    char block[1050];

} BufferElement;

//Method declarations
void *produce( void* inputFile );
void *consume();

//Global Variables
FILE *inFile;
BufferElement *PCbuffer;
const int BLOCK_SIZE_MAX = 1000;
int lineNum = 0;
pthread_t producer;
pthread_t consumer;
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cvFull = PTHREAD_COND_INITIALIZER;
pthread_cond_t cvEmpty = PTHREAD_COND_INITIALIZER;

int main( int argc, char** argv ) {

    //Check for correct number of arguements
    if ( argc != 2 ) {

            fprintf( stderr, "Usage: ./lab7 file\n" );
            exit( -1 );
    }

    //Check to make sure you can open the file for reading
    inFile = fopen( argv[1], "r" );
    if ( inFile == NULL ) {

            printf( "Cannot open %s\n", argv[1] );
            exit( -1 );
    }

    //Initialize the mutex lock
    if ( pthread_mutex_init( &mu, NULL ) != 0 ) {

            fprintf( stderr, "Can't initialize mutex\n" );
            exit( -1 );
    }

    //Initialize the condition variable for producer
    if ( pthread_cond_init( &cvFull, NULL ) != 0 ) {

            fprintf( stderr, "Can't initialize condition variable\n" );
            exit( -1 );
    }

    //Initialize the condition variable for consumer
    if ( pthread_cond_init( &cvEmpty, NULL ) != 0 ) {

            fprintf( stderr, "Can't initialize condition variable\n" );
            exit( -1 );
    }

    //Create the producer thread
    if ( pthread_create( &producer, NULL, produce, ( void* ) argv[1] ) != 0 ) {

            fprintf( stderr, "Error in creating producer thread\n" );
            exit( -1 );
    }

    //Create the consumer thread
    if ( pthread_create( &consumer, NULL, consume, ( void* ) NULL ) != 0 ) {

            fprintf( stderr, "Error in creating consumer thread\n" );
            exit( -1 );
    }

    //Join the producer thread
    if ( pthread_join( producer, NULL ) != 0 ) {

            fprintf( stderr, "Error in thread join" );
            exit( -1 );
    }

    //Join the consumer thread
    if ( pthread_join( consumer, NULL ) != 0 ) {

            fprintf( stderr, "Error in thread join" );
            exit( -1 );
    }

    //Print out the total number of lines
    printf( "\nNumber of lines in file: %d\n", lineNum );

    //Close the input file
    fclose( inFile );

    return 0;
}

/**
 * Producer function for the producer-consumer cycle.  Takes characters
 * and puts them in the buffer
 * @return void* nothing
 */
void* produce( void* inputFile ) {

    printf("bigmoney\n");

    //Declare helper variables
    int temp;
    char fileChar;

    PCbuffer = malloc( sizeof( BufferElement ) ); //Malloc buffer
    fileChar = getc( inFile ); //Get first char

    //Begin the feeding of the buffer
    for( temp = 0; temp != BLOCK_SIZE_MAX; temp++ ) {

            //Take the lock and perform tasks
            if ( pthread_mutex_lock( &mu ) != 0 ) {

                    fprintf( stderr, "Error in mutex_lock\n" );
                    exit( -1 );
            }

            //Wait for thread
            while ( PCbuffer->blockLength == 0 ) {

                    printf("phil");

                    if ( pthread_cond_wait( &cvFull, &mu ) != 0 ) {

                            fprintf( stderr, "Error in cond_wait" );
                            exit( -1 );
                    }
            }

            PCbuffer->block[ temp ] = fileChar;//Adjust block values
            fileChar = getc( inFile ); //Get next char

            //Now take lock away
            if ( pthread_mutex_unlock( &mu ) != 0 ) {

                    fprintf( stderr, "Error in mutex_unlock\n" );
                    exit( -1 );
            }

            //Signal the other thread
            if ( pthread_cond_signal( &cvEmpty ) != 0 ) {

                    fprintf( stderr, "Error in cond_signal" );
                    exit( -1 );
            }

            //Break off if we reach the end of the file
            if( fileChar == EOF ) break;
    }

    printf("moms\n");

    PCbuffer->blockLength = temp; //Update block length

    printf("%d\n", BLOCK_SIZE_MAX);
    printf("%d\n", PCbuffer->blockLength);

    return 0;
}

/**
 * Consumer function for the producer-consumer cycle.  Counts number of
 * lines in the buffer and increments accordingly
 * @return void* nothing
 */
void *consume() {

    printf("jerryjackson\n");

    //Declare helper variables
    char fileChar;

    printf( "%d\n", PCbuffer->blockLength );

    //Count number of lines in buffer
    for( int i = 0; i != PCbuffer->blockLength; i++ ) {

            //Obtain the lock and finish tasks
            if ( pthread_mutex_lock( &mu ) != 0 ) {

                    fprintf( stderr, "Error in mutex_lock\n" );
                    exit( -1 );
            }

            //Wait for thread
            while ( PCbuffer->blockLength == BLOCK_SIZE_MAX ) {

                    printf("hatcher");

                    if ( pthread_cond_wait( &cvEmpty, &mu ) != 0 ) {

                            fprintf( stderr, "Error in cond_wait" );
                            exit( -1 );
                    }
            }

            fileChar = PCbuffer->block[ i ];

            //If we are at the end of a line then we know there's another
            //line to increment up
            if( fileChar == '\n' ) lineNum++;

            //Now take lock away
            if ( pthread_mutex_unlock( &mu ) != 0 ) {

                    fprintf( stderr, "Error in mutex_unlock\n" );
                    exit( -1 );
            }

            //Signal the other thread
            if ( pthread_cond_signal( &cvFull ) != 0 ) {

                    fprintf( stderr, "Error in cond_signal" );
                    exit( -1 );
            }
    }

    //Free the malloced memory
    //free( PCbuffer );
    PCbuffer = NULL;

    return 0;
}

0 个答案:

没有答案