多个线程上每次都有不同的输出

时间:2015-10-19 04:11:12

标签: c multithreading posix conditional-statements mutex

每次运行此程序时,我都会继续获得不同的输出。此外,程序永远不会终止,但停止使用cpu。我不确定发生了什么。

应该读取一个文件,一次一个字符,将其写入缓冲区,如果字符是函数字符则输出它。每个线程处理一个读,写和输出的工作。

程序每次输出不同的字符。

有人可以帮忙吗?

#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>


// Global variables(s) / Shared data
FILE *filePointer;
char input;
char buffer[60] = {'\0'};

// Condition variable(s)
pthread_cond_t characterInput;
pthread_cond_t printingLine;

bool charRead = false;
bool printBuffer = false;

// Mutex to control access to shared data.
pthread_mutex_t lock;

/*
 Thread 1:
 Reads input one character at a time.
 Passes the read character to Thread 2 before another is read.
*/
void *readCharacter(void *arg)
{
    // Begin Critical section
    pthread_mutex_lock(&lock);

    // Receive the character from the user.
    if ((input = fgetc(filePointer)) == EOF) pthread_exit(NULL);

    // Let the other threads know a character has been received.
    charRead = true;
    pthread_cond_signal(&characterInput);

    // End Critical section
    pthread_mutex_unlock(&lock);

    pthread_exit(NULL);
}

/*
 Thread 2:
 Stores characters as received.
 However, these characters ask Thread 2 to take action:

 * – erase last character from buffer

 @ – insert an end-of-line marker into buffer

 $ – delete the last word

 & – remove current incomplete line from buffer
*/
void *receiveCharacter(void *arg)
{
    int bufferIndex = 0;

    // Begin Critical section
    pthread_mutex_lock(&lock);

    // Wait to receive a character.
    if (!charRead) pthread_cond_wait(&characterInput, &lock);
    charRead = false;

    // Check to see if the character is an action.
    switch (input) {
        case '*':
            buffer[bufferIndex--] = '\0';
            break;

        case '@':
            buffer[bufferIndex] = '\0';
            // Signal to print the buffer.
            printBuffer = true;
            pthread_cond_signal(&printingLine);
            break;

        case '$':
            while (bufferIndex >= 0 && buffer[bufferIndex] != ' ')
            {
                buffer[bufferIndex] = '\0';
                bufferIndex--;
            }
            break;

        case '&':
            while (bufferIndex >= 0)
            {
                buffer[bufferIndex] = '\0';
                bufferIndex--;
            }
            break;

        default:
            buffer[bufferIndex] = input;
            bufferIndex++;
            break;
    }
    // END Critical Section
    pthread_mutex_unlock(&lock);

    pthread_exit(NULL);
}

/*
 Thread 3:
 Reads complete lines of characters (an end-of-line character is read).
 Prints the read line and removes it from the buffer.
*/
void *printLine(void *arg)
{
    // Begin Critical section
    pthread_mutex_lock(&lock);

    // Wait for the signal to print the buffer.
    if (!printBuffer) pthread_cond_wait(&printingLine, &lock);
    printBuffer = false;

    // Print the whole buffer.
    int i = 0;
    while (buffer[i] != '\0')
    {
        printf("%c", buffer[i]);
        buffer[i] = '\0';
        i++;
    }

    // End Critical section
    pthread_mutex_unlock(&lock);

    pthread_exit(NULL);
}

// Creates Threads 1, 2, and 3.
int main()
{
    // Thread 1, 2, and 3.
    pthread_t threadOne;
    pthread_t threadTwo;
    pthread_t threadThree;

    // Initialize the mutex.
    if (pthread_mutex_init(&lock, NULL) != 0) perror("Mutex error.\n");

    // Open the file.
    filePointer = fopen("homework4.txt", "r");

    // Wait for the threads to execute.
    while (input != EOF)
    {
        // Create and run the three threads.
        pthread_create(&threadOne, NULL, readCharacter, NULL);
        pthread_create(&threadTwo, NULL, receiveCharacter, NULL);
        pthread_create(&threadThree, NULL, printLine, NULL);
        if(pthread_join(threadOne, NULL) != 0) perror("Join error.\n");
        if(pthread_join(threadTwo, NULL) != 0) perror("Join error.\n");
        if(pthread_join(threadThree, NULL) != 0) perror("Join error.\n");
    }

    // Close the file.
    fclose(filePointer);

    // Destroy the mutex as it is no longer needed.
    if (pthread_mutex_destroy(&lock) != 0) perror("Destroy Mutex Error.\n");

    return 0;
}

0 个答案:

没有答案