我使用信号量创建一个质数检查器。代码执行直到"找到来自"部分和之后崩溃说"分段故障(核心转储)"。在搜索了这个之后,我明白当程序试图访问一部分不可用的内存时会发生这种情况。但是我的代码中没有理解它。请看看,谢谢!
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <vector>
using namespace std;
#define TOTALSPACE 50
vector<int> buffer(TOTALSPACE);
QSemaphore space(TOTALSPACE), avail;
QMutex l;
int prime_from, prime_to, num_threads;
int total = 0, cnumber = 0;
int in = 0, out = 0;
bool b = false;
//-----Generator------
class Generator : public QThread
{
private:
int strt;
int end;
public:
Generator(int a, int b)
{
strt = a;
end = b;
cnumber = strt;
}
void run()
{
while (cnumber < end)
{
space.acquire();
cnumber++;
buffer[in] = cnumber;
in = (in + 1) % TOTALSPACE;
avail.release();
}
b = true;
for (int i = 0; i < num_threads; i++)
{
space.acquire();
buffer[in] = -1;
in = (in + 1) % TOTALSPACE;
avail.release();
}
}
};
//-----------Checker----------
class Checker : public QThread
{
private:
int number;
public:
Checker() {}
void run();
};
void Checker::run()
{
while (1)
{
avail.acquire();
l.lock();
number = buffer[out];
if (number == -1)
{
l.unlock();
break;
}
bool isPrime = false;
for (int i = 2; i <= sqrt(number); i++)
{
if (number%i == 0)
{
isPrime = true;
break;
}
}
out = (out + 1) % TOTALSPACE;
if (isPrime == false)
{
total++;
}
l.unlock();
space.release();
}
}
//-------------Main---------
int main(int argc, char *argv[])
{
num_threads = atoi(argv[1]);
prime_from = atoi(argv[2]);
prime_to = atoi(argv[3]);
cout << " Number of Threads = " << num_threads << endl;
cout << " Primes checking from " << prime_from << " to " << prime_to << endl;
Generator gen(prime_from, prime_to);
gen.start();
Checker* thr[num_threads];
for (int i = 1; i < num_threads; i++)
{
thr[i] = new Checker();
thr[i]->start();
}
gen.wait();
for (int i = 0; i < num_threads; i++)
{
thr[i]->wait();
}
cout << "Total Primes: " << total << endl;
return 0;
}
答案 0 :(得分:3)
有几件事可能导致这种情况发生。首先,你永远不会检查是否提供了足够的参数(argc>3
)。因此,您可以将无效指针传递给atoi
但更有可能的是,您没有初始化thr[0]
,因为您使用for (int i = 1;
启动了初始化循环,但是您在循环中访问thr[0]
以进行同步,因为您使用{{ 1}}。
另外值得注意的是,当您执行or (int i = 0;
时,您使用的是可变长度数组,因为Checker* thr[num_threads];
不是编译时常量。该功能目前不是C ++标准的一部分(不是在C ++ 14中)。所以,如果你想让你的程序可移植,你可以在最后做num_threads
和Checker** thr = new Checker*[num_threads];
,如果你想要勤奋(而不是使用智能指针)。