我有一个像生产者一样工作的Tasker和三个像消费者和共享资源一样工作的CPU。 Tasker读取文件并将其放入共享资源,然后CPU执行并删除该文件。我将环形队列用于FIFO。我发现的问题是由于条件变量,我的Tasker完成后CPU线程没有终止,即它们仍在等待Tasker添加一些东西以将其删除。我希望在清空CPU线程之前先清空共享资源,但它们陷入死锁状态。抱歉,由于我的调试,代码有些混乱并且已更改。如果您能给我一些建议,我将不胜感激。谢谢。
#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);
}
答案 0 :(得分:0)
问题很少。
您应该执行pthread_cond_signal()
和pthread_cond_broadcast()
互斥锁已锁定。目前它们不在互斥锁内。
在cpu()中退出循环之前,您应该解锁互斥锁。
if (ptr->state == 1) //if tasker finished
{
printf(" I quit");
pthread_mutex_unlock(&lock); //Unlock
break;
}
我认为#2是这里的真正问题。一个CPU线程退出并已锁定互斥锁,另一个线程则永远等待该互斥锁。
更新
您正在两个CPU线程之间共享资源。当前,对于每个数据生产,生产者都在广播。这可能会引起一些问题,因为您的数据使用代码不在if (ptr->head != ptr->tail)
之下,我认为,您应该再进行两次更改才能使其正常工作。
task()
)中,不应使用
pthread_cond_broadcast()
,但使用pthread_cond_signal()
。然而
最后,即ptr->state
为1时,您可以
您需要取消阻止所有线程。cpu()
)中,将消费部分放在if (ptr->head
!= ptr->tail)
中,如下所示。A
if (ptr->head == ptr->tail)
{ //check empty condition
if (ptr->state == 1) //if tasker finished
{
//unlock mutex and break
}
//Wait for signal
}
if (ptr->head == ptr->tail)
{ //check empty condition
if (ptr->state == 1) //if tasker finished
{
//unlock mutex and break
}
}
else
{
bt = ptr->buffer[ptr->tail];
//Rest of the consumption code
...
}