如题,写了一个多线程数学计算程序,但是运行时报段错误,代码:
int presentL = 1;
pthread_mutex_t mutex, started;
double result[501];
void *threadMain(void *x) {
pthread_mutex_lock(&started);
pthread_mutex_unlock(&started);
while (1) {
if (presentL > 500) {
pthread_exit(NULL);
}
int operating;
pthread_mutex_lock(&mutex);
operating = presentL;
presentL++;
pthread_mutex_unlock(&mutex);
result[operating] = find(operating / 100.0);
printf("%d\n", operating);
}
}
int main() {
pthread_t threads[6];
srand(12344);
pthread_mutex_init(&mutex, NULL);
pthread_mutex_init(&started, NULL);
pthread_mutex_lock(&started);
printf("Starting...");
for (int i = 0; i < 6; i++) {
pthread_create(&threads[i], NULL, threadMain, NULL);
}
printf("Done\n");
pthread_mutex_unlock(&started);
for (int i = 0; i < 6; i++) {
pthread_join(threads[i], NULL);
}
FILE *out = fopen("111.txt", "w");
for (int i = 0; 1 < 501; i++) {
fprintf(out, "%lf %lf\n", i / 100.0, result[i]);
}
fclose(out);
return 0;
}
其中double find(double)
是一个数学计算函数。程序思路是用6个线程处理500组数据。
为什么会出现段错误?
终端输出:(最后一部分)
493
497
498
500
499
Segmentation fault (核心已转储)
Cygwin x86 Windows XP SP3 gcc 5.3.0
你对 presentL的操作不是 原子的. 典型的 test and set问题.
while (1) {
if (presentL > 500) {
pthread_exit(NULL);
}
int operating;
pthread_mutex_lock(&mutex);
operating = presentL;
presentL++;
pthread_mutex_unlock(&mutex);
result[operating] = find(operating / 100.0);
printf("%d\n", operating);
}
你判 presentL > 500 时, 可能 presentL只有 499. 但是下面 operating = presentL;presentL++;
的时候 presentL可能已经到 502了.
while (1) {
int operating;
pthread_mutex_lock(&mutex);
operating = presentL;
if (operating > 500) {
pthread_exit(NULL);
}
presentL++;
pthread_mutex_unlock(&mutex);
result[operating] = find(operating / 100.0);
printf("%d\n", operating);
}
这至少可以解决segfault.
输出的for循环条件1<501,永不停止直到越界
i 1
你这是找不同吧?