Topic : Multi-Threaded Programming
Author : LUPG
Page : << Previous 15  
Go to page :


*            input.
*            perform an endless loop of reading user input. If user
*            pressed 'e', signal our condition variable and end the thread.
* input: none.
* output: none.
*/
void*
read_user_input(void* data)
{
    int c;

    /* register cleanup handler */
    pthread_cleanup_push(restore_coocked_mode, NULL);

    /* make sure we're in asynchronous cancelation mode so   */
    /* we can be canceled even when blocked on reading data. */
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    /* put screen in raw data mode */
    system("stty raw -echo");

    /* "endless" loop - read data from the user.            */
    /* terminate the loop if we got a 'e', or are canceled. */
    while ((c = getchar()) != EOF) {
 if (c == 'e') {
#ifdef DEBUG
     printf("\n\ngot a 'e'\n\n\r");
     fflush(stdout);
#endif /* DEBUG */
     /* mark that there was a cancel request by the user */
     cancel_operation = 1;
     /* signify that we are done */
     pthread_cond_signal(&action_cond);
     pthread_exit(NULL);
 }
    }

    /* pop cleanup handler, while executing it, to restore cooked mode. */
    pthread_cleanup_pop(1);
}

/*
* function: file_line_count - counts the number of lines in the given file.
* algorithm: open the data file, read it character by character, and count
*            all newline characters.
* input: file name.
* output: number of lines in the given file.
*/
void*
file_line_count(void* data)
{
    char* data_file = (char*)data;
    FILE* f = fopen(data_file, "r");
    int wc = 0;
    int c;

    if (!f) {
 perror("fopen");
 exit(1);
    }

    /* make sure we're in asynchronous cancelation mode so   */
    /* we can be canceled even when blocked on reading data. */
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    while ((c = getc(f)) != EOF) {
 if (c == '\n')
     wc++;
    }

    fclose(f);

    /* signify that we are done. */
    pthread_cond_signal(&action_cond);

    return (void*)wc;
}

/* like any C program, program's execution begins in main */
int
main(int argc, char* argv[])
{
    pthread_t thread_line_count; /* 'handle' of line-counting thread.        */
    pthread_t thread_user_input; /* 'handle' of user-input thread.           */
    void* line_count;   /* return value from line-counting thread.  */

    printf("Checking file size (press 'e' to cancel operation)...");
    fflush(stdout);

    /* spawn the line counting thread */
    pthread_create(&thread_line_count,
     NULL,
     file_line_count,
     (void*)DATA_FILE);
    /* spawn the user-reading thread */
    pthread_create(&thread_user_input,
     NULL,
     read_user_input,
     (void*)DATA_FILE);

    /* lock the mutex, and wait on the condition variable, */
    /* till one of the threads finishes up and signals it. */
    pthread_mutex_lock(&action_mutex);
    pthread_cond_wait(&action_cond, &action_mutex);
    pthread_mutex_unlock(&action_mutex);

#ifdef DEBUG
    printf("\n\rmain: we got signaled\n\n\r");
    fflush(stdout);
#endif /* DEBUG */

    /* check if we were signaled due to user operation        */
    /* cancelling, or because the line-counting was finished. */
    if (cancel_operation) {
 /* we join it to make sure it restores normal */
 /* screen mode before we print out.           */
        pthread_join(thread_user_input, NULL);
 printf("operation canceled\n");
 fflush(stdout);
        /* cancel the file-checking thread */
        pthread_cancel(thread_line_count);
    }
    else {
        /* join the file line-counting thread, to get its results */
        pthread_join(thread_line_count, &line_count);

        /* cancel and join the user-input thread.     */
 /* we join it to make sure it restores normal */
 /* screen mode before we print out.           */
        pthread_cancel(thread_user_input);
        pthread_join(thread_user_input, NULL);

 /* and print the result */
        printf("'%d' lines.\n", (int)line_count);
    }

    return 0;
}


Page : << Previous 15