每次运行此程序时,我都会继续获得不同的输出。此外,程序永远不会终止,但停止使用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;
}