gpt4 book ai didi

c - PThreads.消费者-生产者!打印在不同的文件中

转载 作者:行者123 更新时间:2023-11-30 16:31:54 25 4
gpt4 key购买 nike

我正在尝试使用线程实现生产者 - 消费者。在下面的代码中,除了我尝试打印到 2 个文件之外,运行良好。(一个用于 prod,一个用于 cons)。我使用 fclose(stdout) 。当我在生产者内部删除它时,生产者文件中的打印可以,但消费者不行。当我完全删除时,所有数据都打印到消费者文件中。我的问题是我应该尝试正确打印(我需要消费者在 cons.out.txt 中打印,在 prod_out.txt 中打印生产者)。此外,我没有包含对线程的检查以使其简单,但效果很好。 #include“head.h”

circular_buffer cb;  
pthread_mutex_t lock;
pthread_cond_t cond;


char * data[6]; //is the data taken from cmd(argv[0-6]) first one is the program the other are parameters


int main(int argc , char *argv[]) {
validate(argv,argc); //if command arguments are valid go on
for(int i=0; i < argc; i++){
data[i]=argv[i]; //copy argv array to data array
}

cb_init(&cb,10,sizeof(int)); //initialization of circular buffer for 10 nodes + size of int each node
pthread_t cons, prod;
void *consumer(), *producer();

int rc = pthread_mutex_init(&lock, NULL);
rc = pthread_cond_init(&cond, NULL);

int id[]={1,2}; //prod id is 1 and cons 2

rc = pthread_create(&prod, NULL, producer, &id[0]);
rc = pthread_create(&cons, NULL, consumer, &id[1]);

rc=pthread_join(prod, NULL);
rc=pthread_join(cons, NULL);

rc = pthread_mutex_destroy(&lock);
rc = pthread_cond_destroy(&cond);

cb_free(&cb); //free allocated memory which is alocated in head
return 1;

}
void *consumer(void * id){
int thread_id= *((int*)id); //cast to (int)
int file;
FILE * fp2 = fopen("./cons_out.txt","wb"); //creates new file with "cons_out.txt" name
int i =10;
while(i > 0){
i--;
pthread_mutex_lock(&lock);

while(isEmpty(&cb)){
int rc = pthread_cond_wait(&cond,&lock);
}//end while

int item=0; // item that will be consumed
cb_pop_front(&cb,&item);
file = open("./cons_out.txt", O_APPEND | O_WRONLY, 0777 );//open file as new
if( file == -1 ) {//fail to open file
perror("./cons_out.txt");
return EXIT_FAILURE;
}
fclose(stdout);
dup2( file, STDOUT_FILENO); //change redirections
printf("Consumer %d : %d\n",thread_id,item); //print output to file

pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

} //end while

return NULL;
} //end consumer()

void *producer(void * id){
int thread_id= *((int*)id); //cast to (*int)
int file1;
FILE * fp1 = fopen("./prod_in.txt","wb"); //creates new file with "prod_in.txt" name
for(int i=0; i<10; i++){ //it produce 10 numbers
pthread_mutex_lock(&lock);

while(isFull(&cb)){
int rc = pthread_cond_wait(&cond,&lock);
}//end while

int seed=1;
int item=rand(); // item of this producer
cb_push_back(&cb,&item);
file1 = open("./prod_in.txt", O_APPEND | O_WRONLY, 0777 );//open file as new
if( file1 == -1 ) {//fail to open file
perror("./prod_in.txt");
return EXIT_FAILURE;
}
fclose(stdout);
dup2( file1, STDOUT_FILENO); //change output
printf("Producer %i : %i\n",thread_id,item); //print output to file

pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
} //end for

return NULL;

} //end Producer();

最佳答案

整个进程只有一个打开的文件表,由其中的所有线程共享。该表中有一个条目用于标准输出,并且您的生产者和消费者正在争夺它。目前尚不清楚原因。

我倾向于认为您遇到麻烦的直接原因是 fclose()stdout 流释放了流级资源,尤其是缓冲区和状态跟踪详细信息。 open()文件描述符不提供这些,dup2()文件描述符也不提供这些,将文件描述符转换为表示关闭流的FILE对象.

但我很困惑为什么你让事情变得如此困难。为什么要欺骗文件描述符呢?您的生产者和消费者已经 fopen() 想要的输出文件,从而各自获得与相应文件(fp1fp2)连接的自己的流。在我看来,您所需要做的就是通过 fprintf()etc 写入这些流,而不是花费很多麻烦能够使用 printf() 代替。

这也会更有效,因为您不需要不断打开和关闭文件。正如您已经做的那样,在开始时打开每个选项一次,然后在最后关闭每个选项一次,而您目前未能做到这一点。

关于c - PThreads.消费者-生产者!打印在不同的文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50377533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com