我正在编写代码来计算x ^ 2 + 1作为POSIX C-Code的积分,递归地减半部分。
我知道,我可以使用图书馆,只是为了学习。
e1和e2将在我的main函数中初始化,直接在调用与参数集成之前,如下所示:
e1 = 10E-2;
e2 = 2E-4;
integrate(1.0, 2.0)
代码如下所示:
float e1, e2;
float f(float x)
{
return pow(x, 2) + 1;
}
float f1(float x)
{
return 2 * x;
}
typedef struct integrateArgs
{
float a;
float b;
float result;
} integrateArgs;
float integrate(float a, float b);
void* integrateAsThread(void* args)
{
integrateArgs* myArgs = (integrateArgs*)args;
myArgs->result = integrate(myArgs->a, myArgs->b);
return NULL;
}
float integrate(float a, float b)
{
float diff = b - a;
if(a < 0 || a >= b || diff > 2 || e1 <= 0 || e2 <= 0)
{
return -1;
}
float x1 = (a + b) / 2;
float x2 = f(x1);
if((f1(x1) / x2) > e1 && diff > e2)
{
float half = diff / 2;
float newCenter = a + half;
integrateArgs rightPart = { .a = newCenter, .b = b };
pthread_t thread;
pthread_create(&thread, NULL, integrateAsThread, (void*)&rightPart);
float left = integrate(a, newCenter);
pthread_join(thread, NULL);
return left + rightPart.result;
}
else
{
return diff * x2;
}
}
虽然我没有任何猜测,但似乎有竞争条件。如果我将integrate-method更改为:
float left = integrate(a, newCenter);
pthread_t thread;
pthread_create(&thread, NULL, integrateAsThread, (void*)&rightPart);
pthread_join(thread, NULL);
实际上删除了并行性,它工作正常。如果我使用第一个版本,则每次执行时结果都不同。
任何提示,我做错了什么?
答案 0 :(得分:2)
您不检查pthread_create
的返回值。您的代码可能会创建太多线程,因此您超出了操作系统限制,然后某些子任务从未执行,并且您得到错误的结果。