我有两个线程,它们应该使用相同的内存。主方法应该启动两个线程。TråA必须读取文件的内容,并与TråB共享它。TråB也必须接收TråA共享的数据,并循环通过和计数文件中的字节数。两个线程都运行,但在程序终止前的最后一步I内存段故障。我使用信号量之间的线程通信。这里我的代码:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#define BUFFER_SIZE 4096
typedef struct _Buffer
{
int size;
char data[BUFFER_SIZE];
} Buffer;
sem_t task1, task2;
void *thread_A(void *arg);
void *thread_B(void *arg);
int main(int argc, char *argv[])
{
Buffer *memory = malloc(sizeof(Buffer));
sem_init(&task1, 0, 0);
sem_init(&task2, 0, 0);
pthread_t thread_A_id;
pthread_t thread_B_id;
pthread_create(&thread_A_id, NULL, &thread_A, &memory);
pthread_create(&thread_B_id, NULL, &thread_B, &memory);
if (pthread_join(thread_A_id, NULL) != 0)
{
perror("Error joining thread A");
exit(1);
}
if (pthread_join(thread_B_id, NULL) != 0)
{
perror("Error joining thread B");
exit(1);
}
free(memory);
return 0;
}
void *thread_A(void *arg)
{
Buffer *buffer = (Buffer*) arg;
FILE *pdf_file = fopen("file.pdf", "rb");
if (pdf_file == NULL)
{
perror("Can not open the file");
}
printf("size of struct %ld\n", sizeof(Buffer));
buffer->size = fread(&buffer->data, sizeof(char), BUFFER_SIZE, pdf_file);
fclose(pdf_file);
sem_post(&task1);
sem_wait(&task2);
printf("A is out\n");
return NULL;
}
void *thread_B(void *arg)
{
printf("IAM IN TREAD B");
Buffer *buffer = (Buffer*) arg;
sem_wait(&task1);
int i=0;;
int byte_counts[256] = {0};
while (buffer->size != i) {
unsigned char byte = buffer->data[i];
byte_counts[byte]++;
i++;
}
for (int i = 0; i < 256; i++)
{
printf("Byte-value %02X: %d\n", i, byte_counts[i]);
}
sem_post(&task2);
printf("threadB is done 2\n");
return NULL;
}
2条答案
按热度按时间3mpgtkmj1#
memory
是指向Buffer
(Buffer *
)的指针,通过获取它的地址,可以获得指向缓冲区(Buffer **
)的指针:但在线程函数中,您假设
arg
是Buffer *
:这会导致未定义的行为。
很明显,有一个间接太多;
memory
已经是一个指针,所以我们不需要获取它的地址:ve7v8dk22#
如果文件无法打开,fread将返回-1,并且不检查它,因此thread_B中的循环将首先从buffer-〉data读取垃圾,然后继续超出限制(因为与-1比较)。
因此,首先,fopen()缺少错误处理- thread_a在perror之后继续,其次-fread()之后缺少错误检查。
顺便说一下,在之后检查if(buffer-〉size == i)**while(buffer-〉size!= i)**是多余的:)