- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有 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(¬_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);
}
最佳答案
问题很少。
您应该执行 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)
如下所示。一个
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/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!