Введение
У меня есть вектор entities
, содержащий 44 миллиона имен. Я хочу разделить его на 4 части и обрабатывать каждую часть параллельно. Класс Freebase
содержит функцию loadData()
, которая используется для разделения вектора и вызова функции multiThread
для выполнения обработки.
loadEntities()
читает текстовый файл, содержащий имена. Я не помещал реализацию в класс, потому что это не важноloadData()
разбивает векторentities
, который был инициализирован в конструкторе, на 4 части и добавляет к каждой частиvector<thread> threads
следующим образом:
threads.push_back(thread(&Freebase::multiThread, this, i, i + right, ref(data)));
- multiThread — это функция, в которой я обрабатываю файлы
i
иi+right
— индексы, используемые в цикле for многопоточности для перебора объектов.returnValues
является подфункциейmultiThread
и используется для вызова внешней функции.
Проблема
cout <<"Entity " << entities[i] << endl;
показывает следующие результаты:
- Сущность m.0rzf6wv (хорошо)
- Сущность m.0rzf70 (хорошо)
- Сущность m.068s4h9 m.0n_k8bz (НЕПРАВИЛЬНО)
- Объект Объект m.068s5_1 (НЕВЕРНО)
Последние 2 вывода неверны. Вывод должен быть:
Entity name
нетentity entity name
иentity name name
Это вызывает ошибку сегментации, когда входные данные отправляются в функцию returnValues
. Как я могу это решить?
Исходный код
#ifndef FREEBASE_H
#define FREEBASE_H
class Freebase
{
public:
Freebase(const std::string &, const std::string &, const std::string &, const std::string &);
void loadData();
private:
std::string _serverURL;
std::string _entities;
std::string _xmlFile;
void multiThread(int,int, std::vector<std::pair<std::string, std::string>> &);
//private data members
std::vector<std::string> entities;
};
#endif
#include "Freebase.h"
#include "queries/SparqlQuery.h"
Freebase::Freebase(const string & url, const string & e, const string & xmlFile, const string & tfidfDatabase):_serverURL(url), _entities(e), _xmlFile(xmlFile), _tfidfDatabase(tfidfDatabase)
{
entities = loadEntities();
}
void Freebase::multiThread(int start, int end, vector<pair<string,string>> & data)
{
string basekb = "PREFIX basekb:<http://rdf.basekb.com/ns/> ";
for(int i = start; i < end; i++)
{
cout <<"Entity " << entities[i] << endl;
vector<pair<string, string>> description = returnValues(basekb + "select ?description where {"+ entities[i] +" basekb:common.topic.description ?description. FILTER (lang(?description) = 'en') }");
string desc = "";
for(auto &d: description)
{
desc += d.first + " ";
}
data.push_back(make_pair(entities[i], desc));
}
}
void Freebase::loadData()
{
vector<pair<string, string>> data;
vector<thread> threads;
int Size = entities.size();
//split database into 4 parts
int p = 4;
int right = round((double)Size / (double)p);
int left = Size % p;
float totalduration = 0;
vector<pair<int, int>> coordinates;
int counter = 0;
for(int i = 0; i < Size; i += right)
{
if(i < Size - right)
{
threads.push_back(thread(&Freebase::multiThread, this, i, i + right, ref(data)));
}
else
{
threads.push_back(thread(&Freebase::multiThread, this, i, Size, ref(data)));
}
}//end outer for
for(auto &t : threads)
{
t.join();
}
}
vector<pair<string, string>> Freebase::returnValues(const string & query)
{
vector<pair<string, string>> data;
SparqlQuery sparql(query, _serverURL);
string result = sparql.retrieveInformations();
istringstream str(result);
string line;
//skip first line
getline(str,line);
while(getline(str, line))
{
vector<string> values;
line.erase(remove( line.begin(), line.end(), '\"' ), line.end());
boost::split(values, line, boost::is_any_of("\t"));
if(values.size() == 2)
{
pair<string,string> fact = make_pair(values[0], values[1]);
data.push_back(fact);
}
else
{
data.push_back(make_pair(line, ""));
}
}
return data;
}//end function
data.push_back
из своих потоков и небезопасно изменяете вектор из нескольких потоков - поправьте меня, если я ошибаюсь. Я думаю, что это причина вашей проблемы с segfault. - person Arnon Zilca   schedule 24.06.2015returnValues
, вdata
- person Hani Goc   schedule 24.06.2015cout
влияет на работуreturnValues
? Отсутствие синхронизации вывода приведет к искажению вывода, но это единственный эффект, который должен быть. Ваша проблема, скорее всего, связана с другой проблемой синхронизации (для другого общего ресурса). - person Sander De Dycker   schedule 24.06.2015entities
проблема в том, что когда я добавляю элемент вdata
. это правильно? - person Hani Goc   schedule 24.06.2015push_back
, который все равно добавляет элементы. Если вы их обновили, я думаю, все будет в порядке. - person Arnon Zilca   schedule 24.06.2015