递归 POSIX 线程代码中的竞争条件?
Race condition in recursive POSIX thread code?
我正在编写代码来计算 x^2+1 的积分作为 POSIX C 代码,通过递归地将部分减半。
我知道,我可以使用图书馆,它只是为了学习。
e1 和 e2 将在我的主函数中初始化,直接在调用带有参数的集成之前,如下所示:
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;
}
}
虽然我不知道在哪里,但似乎存在竞争条件。如果我将集成方法更改为:
float left = integrate(a, newCenter);
pthread_t thread;
pthread_create(&thread, NULL, integrateAsThread, (void*)&rightPart);
pthread_join(thread, NULL);
这实际上消除了并行性,它工作正常。如果我使用第一个版本,每次执行的结果都不同。
任何提示,我做错了什么?
您没有检查 pthread_create
的 return 值。很可能是你的代码创建了太多的线程,以至于超过了操作系统的限制,然后一些子任务永远不会执行,你得到了错误的结果。
我正在编写代码来计算 x^2+1 的积分作为 POSIX C 代码,通过递归地将部分减半。
我知道,我可以使用图书馆,它只是为了学习。
e1 和 e2 将在我的主函数中初始化,直接在调用带有参数的集成之前,如下所示:
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;
}
}
虽然我不知道在哪里,但似乎存在竞争条件。如果我将集成方法更改为:
float left = integrate(a, newCenter);
pthread_t thread;
pthread_create(&thread, NULL, integrateAsThread, (void*)&rightPart);
pthread_join(thread, NULL);
这实际上消除了并行性,它工作正常。如果我使用第一个版本,每次执行的结果都不同。
任何提示,我做错了什么?
您没有检查 pthread_create
的 return 值。很可能是你的代码创建了太多的线程,以至于超过了操作系统的限制,然后一些子任务永远不会执行,你得到了错误的结果。