【发布时间】:2012-11-09 06:18:44
【问题描述】:
所以,我正在为同时运行 4 个线程的类编写程序。我的程序运行良好,除了它在运行时停止的事实。我不确定这是否与我设置 pthread_cond_wait 的方式有关,或者是否与其他原因有关。我已经多次手动跟踪程序,但找不到解释。
这是我的代码:
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#include <stdlib.h>
//#define TENP .1
//#define FIFTP .15
void *tenPercentA();
void *tenPercentB();
void *fiftPercentC();
void *fiftPercentD();
pthread_cond_t aPirate;
pthread_cond_t bPirate;
pthread_cond_t cPirate;
pthread_cond_t dPirate;
pthread_mutex_t mutex;
int pearls = 1000;
int main()
{
pthread_t tid;
pthread_setconcurrency(4);
pthread_create(&tid, NULL, (void *(*)(void *))tenPercentA, NULL);
pthread_create(&tid, NULL, (void *(*)(void *))tenPercentB, NULL);
pthread_create(&tid, NULL, (void *(*)(void *))fiftPercentC, NULL);
pthread_create(&tid, NULL, (void *(*)(void *))fiftPercentD, NULL);
pthread_exit(0);
}
void *tenPercentA(){
int totalA = 0;
double tempA = 0;
while(pearls > 0){
pthread_mutex_lock(&mutex);
if(pearls > 0){
tempA = pearls * .1;
tempA = ceil(tempA);
totalA = totalA + tempA;
pearls = pearls - tempA;
printf("Pirate A stole %1.1f pearls.\n", tempA);
printf("Pirate A's total: %d\n", totalA);
sleep(1);
pthread_cond_broadcast (&bPirate);
pthread_cond_broadcast (&cPirate);
pthread_cond_broadcast (&dPirate);
tempA = 0.0;
}
else{
printf("No more pearls!\n");
exit(0);
}
pthread_mutex_unlock(&mutex);
pthread_cond_wait (&aPirate, &mutex);
}
}
void *tenPercentB(){
int totalB = 0;
double tempB = 0;
while(pearls > 0){
pthread_mutex_lock(&mutex);
if(pearls > 0){
tempB = pearls * .1;
tempB = ceil(tempB);
totalB = totalB + tempB;
pearls = pearls - tempB;
printf("Pirate B stole %1.1f pearls.\n", tempB);
printf("Pirate B's total: %d\n", totalB);
sleep(1);
pthread_cond_broadcast (&aPirate);
pthread_cond_broadcast (&cPirate);
pthread_cond_broadcast (&dPirate);
tempB = 0.0;
}
else{
printf("No more pearls!\n");
exit(0);
}
pthread_mutex_unlock(&mutex);
pthread_cond_wait (&bPirate, &mutex);
}
}
void *fiftPercentC(){
int totalC = 0;
double tempC = 0;
while(pearls > 0){
pthread_mutex_lock(&mutex);
if(pearls > 0){
tempC = pearls * .15;
tempC = ceil(tempC);
totalC = totalC + tempC;
pearls = pearls - tempC;
printf("Pirate C stole %1.1f pearls.\n", tempC);
printf("Pirate C's total: %d\n", totalC);
sleep(1);
pthread_cond_broadcast (&bPirate);
pthread_cond_broadcast (&aPirate);
pthread_cond_broadcast (&dPirate);
tempC = 0.0;
}
else{
printf("No more pearls!\n");
exit(0);
}
pthread_mutex_unlock(&mutex);
pthread_cond_wait (&cPirate, &mutex);
}
}
void *fiftPercentD(){
int totalD = 0;
double tempD = 0;
while(pearls > 0){
pthread_mutex_lock(&mutex);
if(pearls > 0){
tempD = pearls * .15;
tempD = ceil(tempD);
totalD = totalD + tempD;
pearls = pearls - tempD;
printf("Pirate D stole %1.1f pearls.\n", tempD);
printf("Pirate D's total: %d\n", totalD);
sleep(1);
pthread_cond_broadcast (&bPirate);
pthread_cond_broadcast (&cPirate);
pthread_cond_broadcast (&aPirate);
tempD = 0.0;
}
else{
printf("No more pearls!\n");
exit(0);
}
pthread_mutex_unlock(&mutex);
pthread_cond_wait (&dPirate, &mutex);
}
}
下面是它在运行时执行的一些示例输出:
Pirate A stole 100.0 pearls.
Pirate A's total: 100
Pirate B stole 90.0 pearls.
Pirate B's total: 90
Pirate C stole 122.0 pearls.
Pirate C's total: 122
我唯一可以解释的想法是,当 CPU 调度程序有两个线程准备好背靠背运行时,程序会卡住。例如(在调度队列中):A |乙| C | C | D. 有什么建议吗?
【问题讨论】:
-
不一定相关,但您可能需要在 pthread_cond_wait 上查看您的文档。我看到您在等待之前立即解锁互斥锁,这是多余的。等待将为您解锁。同样,在从 pthread_cond_wait 返回时,互斥锁被锁定,从而使您在冗余之后立即重新锁定。我建议您查看您的 pthreads 书(或者我可能需要,因为它已经有一段时间了)。
-
“我的程序运行良好,除了它在运行时停止”——这听起来并不完美……
-
现在我看着它,反正没关系,因为我看不到 pthread_cond_init 甚至 创建 那些条件变量,所以它不像任何等待无论如何都要工作。
-
条件 init 位于程序的顶部。 pthread_cond_t 创建一个等待条件。
-
对于小奇迹很好,因为我刚刚下载了上面的源代码,编译了它,第一个 pthread_mutex_lock 调用失败,错误为 22 (EINVAL),这正是互斥对象应该返回的内容无效。仅仅声明它们是不够的;它们需要以一种或另一种方式初始化。这些不是。
标签: c multithreading unix