gpt4 book ai didi

c - 在此 pthreaded C 程序中避免死锁的一些提示

转载 作者:太空宇宙 更新时间:2023-11-04 04:12:10 25 4
gpt4 key购买 nike

我有 1 个充当生产者的任务器和 3 个充当消费者和共享资源的 CPU。 Tasker 读取文件并将其放入共享资源,CPU 执行并删除它。我为 FIFO 使用了环形队列。我发现的问题是 CPU 线程在我的 Tasker 完成后没有终止,因为条件变量,即它们仍在等待 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(&not_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(&not_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(&not_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(&not_full);
//printf("CPU waiting3 \n" );
}
printf("I broke \n");
//pthread_cancel(pthread_self());
pthread_exit(0);
}

最佳答案

问题很少。

  1. 您应该执行 pthread_cond_signal()pthread_cond_broadcast()互斥量锁定。目前它们在互斥体之外。

  2. 在 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) 下 在我看来,您应该再做两处更改才能正常工作。

  1. 在生产者函数(task())中,你不应该使用pthread_cond_broadcast() 但使用 pthread_cond_signal()。然而最后,即当 ptr->state 为 1 时,您可以广播为您需要解除对所有线程的阻塞。
  2. 在消费函数(cpu())中,将消费部分放在if (ptr->head
    != ptr->tail)
    如下所示。

一个

   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
...
}

关于c - 在此 pthreaded C 程序中避免死锁的一些提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55886950/

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