У меня есть 1 Tasker, который действует как производитель, и 3 CPU, которые действуют как потребители и общие ресурсы.Tasker читает файл и помещает его в общий ресурс, а процессоры исполняют и удаляют его.Я использовал кольцевую очередь для FIFO.Проблема, которую я обнаружил, состоит в том, что потоки ЦП не завершаются после того, как завершается работа моего Tasker из-за условных переменных, то есть они все еще ждут, пока Tasker добавит что-то для их удаления.Я хочу, чтобы общий ресурс очищался до того, как я просто уничтожил потоки процессора, но они зашли в тупик.Извините, код немного грязный и изменился из-за моих отладок.Буду признателен, если кто-нибудь из вас даст мне несколько советов о том, как это сделать.Спасибо.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h> //used for exit
#include <string.h>
#include <unistd.h> // sleep function
#include <string.h>
#include <stdbool.h>
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER; //check till not full
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER; //till not empty
void *task(void *n); //function of pthread
void *cpu(void *n); //function of pthread
typedef struct
{
int *buffer; //;//dynamic buffer
int head;
int tail;
int buffsize;
int state;
} queue;
//globals
pthread_t tid, cid1, cid2, cid3; //id
//queue *ptr; //our object
FILE *fwptr; //log file
int tasker;
int main()
{
queue pt; //initialize first
queue *ptr = &pt;
ptr->head = 0;
ptr->tail = 0;
ptr->buffer = (int *)malloc(sizeof(int) * 5);
ptr->buffsize = 5;
fwptr = fopen("fnew.txt", "w+"); //log
pthread_create(&tid, NULL, &task, ptr);
sleep(1);
pthread_create(&cid1, NULL, &cpu, ptr);
//pthread_create(&cid1, NULL, &cpu, ptr);
pthread_create(&cid2, NULL, &cpu, ptr);
pthread_create(&cid3, NULL, &cpu, ptr);
pthread_join(tid, NULL);
//pthread_mutex_lock(&lock);
tasker = 1; //tasker finished so now close when empty, noneed ot mutex bc 1 writer
//pthread_mutex_unlock(&lock);
printf("Main finish1 \n");
//pthread_exit(&cid1);
pthread_join(cid1, NULL);
printf("Main finish2 \n");
pthread_join(cid2, NULL);
pthread_join(cid3, NULL);
fclose(fwptr);
return 0;
}
//TASK///////////////////
void *task(void *param)
{
queue *ptr = (queue *)param;
FILE *frptr = fopen("task_file", "r");
if (frptr == NULL)
printf("Reader File not opened");
int burst;
char data[15];
// int i=0;
int c = 1;
while ((fscanf(frptr, "%s %d", data, &burst)) != EOF)
{
pthread_mutex_lock(&lock);
if (((ptr->head + 1) % ptr->buffsize) == ptr->tail) //adding remainder here too
{ //check full condition
printf("full and Writer waiting\n");
pthread_cond_wait(¬_full, &lock);
}
ptr->buffer[ptr->head] = burst; //write burst time in buffer
ptr->head = (ptr->head + 1) % ptr->buffsize; // for ring queue
printf("Tasker Writes data : %s %d \n", data, burst);
fprintf(fwptr, "Tasker is Writing : %s %d \n", data, burst);
if (burst == 20)
ptr->state = 1;
pthread_mutex_unlock(&lock);
pthread_cond_broadcast(¬_empty);
//sleep(0.25);
c++;
}
printf("End of file");
tasker = 1;
fclose(frptr);
pthread_exit(0);
}
//CPU////////////////
void *cpu(void *param)
{
queue *ptr = (queue *)param;
int bt, i = 0, j = 0;
//sleep(1);
for (;;)
{
pthread_mutex_lock(&lock);
//printf("%s", tasker ? "true" : "false");
if (ptr->head == ptr->tail)
{ //check empty condition
if (ptr->state == 1) //if tasker finished
{
printf(" I quit");
break;
}
printf("CPU head %d tail %d \n", ptr->head, ptr->tail);
//printf("Tasker: %s \n",tasker?"TRUE":"FALSE" );
printf("Tasker: %d \n", tasker);
printf("CPU waiting \n");
pthread_cond_wait(¬_empty, &lock);
}
if (ptr->head == ptr->tail)
{ //check empty condition
if (ptr->state == 1) //if tasker finished
{
printf(" I quit");
break;
}
}
bt = ptr->buffer[ptr->tail];
printf(" Execute blast time: %d \n", bt);
//if ((ptr->head == ptr->tail) && (tasker == 1))
//{ //check empty condition
//ptr->state=1;
//}
// printf("CPU head %d tail %d \n",ptr->head,ptr->tail );
fprintf(fwptr, "CPU is Writing : %d \n", bt);
ptr->tail = (ptr->tail + 1) % ptr->buffsize;
//printf("CPU waiting \n" );
//if (ptr->state = 1) break;
//printf("CPU waiting1 \n" );
pthread_mutex_unlock(&lock);
//printf("CPU waiting2 \n" );
pthread_cond_signal(¬_full);
//printf("CPU waiting3 \n" );
}
printf("I broke \n");
//pthread_cancel(pthread_self());
pthread_exit(0);
}