首页 > 多线程数学计算程序出错怎么办?

多线程数学计算程序出错怎么办?

如题,写了一个多线程数学计算程序,但是运行时报段错误,代码:

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
你这是找不同吧?

【热门文章】
【热门文章】