我有一个程序应该使用多个线程将文件的内容完全复制到另一个文件。读取器线程从文件中读取一行并将其存储在循环缓冲区中。然后,写入器线程从缓冲区读取并写入文件。但是我收到了分段错误而且没有写入文件。知道我为什么会出现分段错误,或者有什么方法可以找出导致错误的原因?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
FILE *inputFile;
FILE *outputFile;
pthread_mutex_t mutex;
int endOfFile = 0;
typedef struct bufferStruct{
int capacity;
int size;
int head;
int tail;
char **data;
}buffer;
buffer * bufferInit(int maxElements){
buffer *buf;
buf = (buffer *)malloc(sizeof(buffer));
buf->data = (char**)malloc(sizeof(char*)*maxElements);
buf->size = 0;
buf->capacity = maxElements;
buf->head = 0;
buf->tail = -1;
return buf;
}
void popFront(buffer *buf){
if(buf->size != 0){
free(buf->data);
buf->size--;
buf->head++;
if(buf->head == buf->capacity){
buf->head = 0;
}
}
return;
}
char* front(buffer *buf){
if(buf->size != 0){
return buf->data[buf->head];
}
return NULL;
}
void pushBack(buffer *buf, char *data){
if(buf->size == buf->capacity){
printf("Queue is Full\n");
}
else{
buf->size++;
buf->tail = buf->tail + 1;
if(buf->tail == buf->capacity){
buf->tail = 0;
}
buf->data[buf->tail] = (char *) malloc((sizeof data + 1)* sizeof(char));
strcpy(buf->data[buf->tail], data);
}
return;
}
buffer *buf;
void* reader(void* arg){
char line[1024];
while(endOfFile != 1){
fgets(line, sizeof(line), inputFile);
printf("Line read: %s", line);
pushBack(buf, line);
if(feof(inputFile)){
endOfFile = 1;
}
}
pthread_exit(0);
}
void* writer(void* arg){
char *line;
while(endOfFile != 1){
pthread_mutex_lock(&mutex);
line = front(buf);
fputs(line, outputFile);
popFront(buf);
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}
int main(int argc, char **argv){
if (argc < 4) {
printf("Usage: %s <input file> <output file> <number>\n", argv[0]);
exit(-1);
}
inputFile = fopen(argv[1], "r");
outputFile = fopen(argv[2], "w");
int numOfThreads = atoi(argv[3]);
buf = bufferInit(16);
pthread_t readerTids[numOfThreads];
pthread_t writerTids[numOfThreads];
pthread_mutex_init(&mutex, NULL);
for(int i = 0; i < numOfThreads; i++){
if(endOfFile != 1){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&readerTids[i], &attr, reader, NULL);
pthread_create(&writerTids[i], &attr, writer, NULL);
printf("Thread %d created\n", i);
}
}
for (int i = 0; i < numOfThreads; i++) {
pthread_join(readerTids[i], NULL);
pthread_join(writerTids[i], NULL);
}
fclose(inputFile);
fclose(outputFile);
}
答案 0 :(得分:1)
考虑读者线程比编写者线程慢的可能性。只有作者线程持有锁,锁定和解锁,不会被读者困扰。如果作者在读者尚未更新缓冲区时尝试使用缓冲区怎么办?使用线程同步,比如信号量,它没有任何所有权问题。
void* reader(void* arg){
char line[1024];
while(endOfFile != 1){
fgets(line, sizeof(line), inputFile);
printf("Line read: %s", line);
pushBack(buf, line);
--- Lock semaphore here---
if(feof(inputFile)){
endOfFile = 1;
}
}
pthread_exit(0);
}
void* writer(void* arg){
char *line;
while(endOfFile != 1){
-- Unlock semaphore here---
line = front(buf);
fputs(line, outputFile);
popFront(buf);
}
pthread_exit(0);
}
与互斥锁不同,两个线程之间可以使用相同的信号量。这有助于您同步两个线程。