C 3线程和消费者-生产者信号量问题
线程并发新手在这里。因此,我的encrypt_线程有时会挂起,我很确定这是因为我使用信号量的方式 我的程序的功能:C 3线程和消费者-生产者信号量问题,c,multithreading,concurrency,semaphore,C,Multithreading,Concurrency,Semaphore,线程并发新手在这里。因此,我的encrypt_线程有时会挂起,我很确定这是因为我使用信号量的方式 我的程序的功能: read_from_file是一个线程,它将文件中的字符一次读取一个字符到输入缓冲区。每次这样做时,它会将\u输入\u缓冲区中的空\u减少1,并将\u输入\u缓冲区中的满\u增加1。如果\u input中的empty\u为0,则它将等待来自加密线程的post(&empty\u input\u buffer) 加密线程等待来自读取线程的post(&full_in_input_buff
int main(int argc, char *argv[]){
//sem_init(&encrypt_signals_read, 0, 1);
int buf_size;
file_in = fopen(argv[1], "r");
file_out = fopen(argv[2], "w");
take_input(&buf_size);
struct thread_args args = {
malloc(sizeof(char)*buf_size),
malloc(sizeof(char)*buf_size),
buf_size,
0,
};
sem_init(&empty_in_input,0,buf_size);
sem_init(&empty_in_output,0,buf_size);
sem_init(&full_in_input_buffer,0,0);
sem_init(&full_in_output_buffer,0,0);
//creating threads
pthread_t read_thread,encrypt_thread,write_thread;
if(pthread_create(&read_thread,NULL,read_from_file,&args) != 0){
printf("Error creating read thread!");
}
if(pthread_create(&encrypt_thread,NULL,encrypt,&args) != 0){
printf("Error creating encrypt thread!");
}
if(pthread_create(&write_thread,NULL,write_to_file,&args) != 0){
printf("Error creating write thread!");
}
pthread_join(read_thread,NULL);
pthread_join(encrypt_thread,NULL);
pthread_join(write_thread,NULL);
fclose(file_in);
fclose(file_out);
}
读线程:
void* read_from_file(void* args){
struct thread_args* shared = (struct thread_args*) args;
char c = '0';
int i = 0;
int val,val1,val2,val3;
if (file_in != NULL){
do{
c = fgetc(file_in);
if(i >= shared->buffer_size)
i = 0;
sem_wait(&empty_in_input);
shared->input_buffer[i] = c;
sem_post(&full_in_input_buffer);
i++;
}while(c != EOF);
}
if (ferror(file_in) != 0 ) {
fputs("Error reading file", stderr);
exit(1);
}
}
加密线程:
void* encrypt(void* args){
struct thread_args* shared = (struct thread_args*) args;
int s = 1;
int i = 0;
char c = '0';
int val,val1,val2,val3,val4;
fill_letters_arr(0);
do{
if(i >= shared->buffer_size)
i = 0;
sem_wait(&full_in_input_buffer);
c = shared->input_buffer[i];
sem_post(&empty_in_input);
if(is_in_letters(&c) == true){
encrypt_letter(&s,&c);
}
sem_wait(&empty_in_output);
shared->output_buffer[i] = c;
sem_post(&full_in_output_buffer);
i++;
}while(c != EOF);
}
写入线程:
void* write_to_file(void* args){
struct thread_args* shared = (struct thread_args*) args;
char c = '0';
int i = 0;
int val,val1,val2,val3;
if (file_out != NULL){
while(c != EOF){
if(i >= shared->buffer_size)
i = 0;
sem_wait(&full_in_output_buffer);
c = shared->output_buffer[i];
fputc(c,file_out);
sem_post(&empty_in_output);
i++;
}
}
if (ferror(file_in) != 0 ) {
fputs("Error reading file", stderr);
}
}
您没有发布完整的、可复制的程序,因此猜测: 1) 你有一个可疑的使用EOF。按照惯例,您将getc的返回视为int;这可以覆盖所有有效字符值以及EOF。这还可以防止编译器认为未签名字符是合理的默认值。无论如何,您可能应该选择一个不同的sentinal值来通过缓冲区来指示EOF 在: 2) 因为您给它一个负值(EOF将截断为(char)-1),所以如果您将它用作索引,您可能会得到一些令人惊讶的值 3) 如果您的加密信碰巧生成了一个0xff作为加密版本,那么它将被此和最后阶段解释为EOF;但第一阶段仍将尝试愉快地阅读文字 概述:EOF不是字符值,它是int
if(is_in_letters(&c) == true){
encrypt_letter(&s,&c);
}