正如所写,这个程序有许多问题。但种族条件和其他类似的线状污秽不在其中。
公共静态类变量是一个非常糟糕的主意。它们基本上只是范围全局变量。它们中的大多数在初始化后不会改变。他们应该是
const
成员变量。
也许如果你在一开始就更仔细、更清晰地设计了你的程序,你就不会犯下以后很难发现的错误。
这就是为什么写得更好。我忠实地复制了你所做的大部分事情。我对你的所作所为还不太了解,你做的比这更好:
//#include "DB.hpp"
#include <thread>
#include <vector>
#include <string>
#include <mutex>
#include <algorithm>
#include <iostream>
#include <atomic>
using namespace std;
class data
{
public:
data(int64_t no_of_threads, int64_t no_of_subscribers, int64_t starting_imsi)
: no_of_threads_(no_of_threads), no_of_subscribers_(no_of_subscribers),
starting_imsi_(starting_imsi),
error_count_(0),
cur_imsi_(0)
{
cur_imsi_ = starting_imsi;
}
int64_t next_imsi() {
if ((cur_imsi_ - starting_imsi_) >= no_of_subscribers_) {
return -1;
} else {
return ++cur_imsi_;
}
}
void add_errors(int64_t l_count)
{
lock_guard<mutex> lg(mtx_error_count_);
error_count_ += l_count;
}
void add_imsi_list(vector<string> const & list)
{
lock_guard<mutex> lg(mtx_imsi_list_);
imsi_list_.insert(imsi_list_.end(), list.begin(), list.end());
}
void sort_imsi_list()
{
// Probably not necessary, but to be thorough.
lock_guard<mutex> lg(mtx_imsi_list_);
sort(imsi_list_.begin(), imsi_list_.end());
}
int64_t imsis_used() const { return cur_imsi_ - starting_imsi_; }
int64_t error_count() const {
lock_guard<mutex> lg(mtx_error_count_);
return error_count_;
}
int64_t thread_count() const { return no_of_threads_; }
vector<string> const &get_imsi_list() const { return imsi_list_; }
private:
const int64_t no_of_threads_;
const int64_t no_of_subscribers_;
const int64_t starting_imsi_;
atomic<int64_t> cur_imsi_;
mutable mutex mtx_error_count_; // Never const
int64_t error_count_; //No. of IMSIs which couldn't be written.
mutable mutex mtx_imsi_list_; // Never const
vector<string> imsi_list_;
};
int main(int argc, char* argv[])
{
if (argc != 3)
{
cout << endl << "Error in input parameters" << endl;
cout << endl << argv[0]
<< "[No_of_threads] [No_of_subscribers] [NODE_IP]" << endl;
cout << "e.g. " << argv[0] << "10 200000 10.32.129.66" << endl;
return 1;
}
data imsi_generator(stoi(argv[1]), stoi(argv[2]), 405862999999999);
// DB::InitDBConnection(argv[3]); //This will initialise the DB connection with the IP
vector<thread> t;
for(int i=0;i<imsi_generator.thread_count();i++)
{
t.emplace_back([&imsi_generator]
{
int64_t errorCount = 0, temp_imsi;
vector<string> temp_list;
temp_imsi = imsi_generator.next_imsi();
while (temp_imsi != -1)
{
string const l_imsi = to_string(temp_imsi);
temp_list.push_back(l_imsi);
// ReturnCode status = DB::rtInsertImsi(l_imsi);
//
// if (status != INSERT_OK)
// ++errorCount;
temp_imsi = imsi_generator.next_imsi();
}
imsi_generator.add_errors(errorCount);
imsi_generator.add_imsi_list(temp_list);
});
}
for (auto &x : t)
x.join();
imsi_generator.sort_imsi_list();
cout << endl << "IMSI LIST" << endl;
// Printing the IMSIs which were entered.
for (auto const &x : imsi_generator.get_imsi_list())
cout << x << endl;
cout << endl << "Number of Imsis used: " << imsi_generator.imsis_used();
cout << endl << "Number of errors: " << imsi_generator.error_count();
return 0;
}