我使用4个线程,我的代码让4个线程处理1/4的10000 int,并找到该季度中的所有素数。(我知道这不是一个很顺利的解决方案…(
{
...
for (int o{my_data->thread_id*2500}; o < (my_data->thread_id *2500) +2500; o++){
if (prime(o) == true)
ss << o << "n" ;
}
...
}
现在,当我尝试将其用于100000 int时,我会得到溢出:
threads.cpp:46:68:运行时错误:有符号整数溢出:1103437824*25000无法在类型"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
似乎没有介于0
和NUM_THREADS - 1
之间的值。它似乎具有值1103437824
。这可能是因为my_data
由于竞争条件而变成了一个悬空指针。
CCD_ 6指向主线程中的CCD_。但是,一旦主线程调用pthread_exit
,该对象的生存期就会结束。因此,在此之后,其他线程的my_data
指针将变为悬空指针,这意味着它不再指向有效对象。取消引用这样的指针会导致未定义的行为。
最好的解决方案可能是主线程在从函数main
返回或调用pthread_exit
之前,在所有工作线程上调用pthread_join
。这样,就可以保证主线程的t_d
数组的生存期超过工作线程my_data
指针的生存期,这样这些指针就永远不会悬空。