再次使用 pthreads:为什么我的线程函数中的 for 循环会产生溢出?

pthreads again: why does the for-loop inside my thread function generate overflow?

我使用 4 个线程,我的代码让 4 个线程处理 10000 个整数的 1/4 四分之一,并找到该四分之一的所有质数。 (我知道这不是一个很顺利的解决方案...)

{
...
   for (int  o{my_data->thread_id*2500}; o <  (my_data->thread_id *2500) +2500; o++){
        if (prime(o) == true)
            ss << o << "\n"  ;
   }
...
}

现在,当我尝试将其用于 100000 个整数时,出现溢出:

threads.cpp:46:68: runtime error: signed integer overflow: 1103437824 * 25000 cannot be represented in type 'int'

我不明白。因为数字“1103437824”不应该是 0、1、2 或 3?

我的代码:

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <math.h>
#include <sstream>


#define NUM_THREADS 4

using namespace std;

bool prime(int n)
{   
    if (n == 1) { return false; };
    if ((n == 2) || (n == 3)) { return true; };
    if ((n % 2 == 0 ) || (n % 3 == 0)) { return false; };

    int sqrt_n{ 0 };

    sqrt_n = sqrt(n);
    
    int  i{ 5 };
    
    while (i <= sqrt_n) {
        
        if (n % i == 0) return false;
        
        i += 2;
    }
    
    return true;
}
struct thread_data {
   int thread_id;
   int  number;
};


void *worker(void *threadarg) {
   struct thread_data *my_data;
   my_data = (struct thread_data *) threadarg;

   std::stringstream ss;
   ss << "Thread ID : " << my_data->thread_id << "\n";
   for (int  o{my_data->thread_id*25000}; o <  (my_data->thread_id *25000) +25000; o++){
        if (prime(o) == true)
            ss << o << "\n"  ;
   }
   std::cout << ss.str ();
   pthread_exit(NULL);
}

int main () {
        
   pthread_t threads[NUM_THREADS];
   struct thread_data t_d[NUM_THREADS];
   int rr;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      t_d[i].thread_id = i;
         
      rr = pthread_create(&threads[i], NULL, worker, (void *)&t_d[i]);
      
      if (rr) {
         cout << "Error:unable to create thread," << rr << endl;
         exit(-1);
      }
   }
    pthread_exit(NULL); 
}```

根据该错误消息,my_data->thread_id 似乎没有介于 0NUM_THREADS - 1 之间的值。它似乎具有 1103437824 的值。这可能是因为 my_data 变成了 dangling pointer, due to a race conditon.

my_data 指向主线程中的 t_d 数组。但是,一旦主线程调用 pthread_exit,该对象的生命周期就结束了。因此,发生这种情况后,其他线程的 my_data 指针变为悬空,这意味着它不再指向有效对象。取消引用此类指针会导致未定义的行为。

最好的解决方案可能是主线程在所有工作线程上调用 pthread_join,然后再从函数 main 调用 returns 或调用 pthread_exit。这样,可以保证主线程的 t_d 数组的生命周期超过工作线程的 my_data 指针的生命周期,因此这些指针永远不会悬空。