Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.02.2019, 19:11   #1
Rakf
 
Регистрация: 03.12.2016
Сообщений: 4
По умолчанию [C++] Есть программа, суть к-рой считать с файла, записать в дерево, считать с дерева. Без многопоточности все работает норм. А вот с потоками проблема. вылазит ошибка сегментации

Есть программа, суть которой считать с файла, записать в дерево, считать с дерева. Без многопоточности все работает норм. А вот с потоками проблема
Код:
#include <string>
#include <vector>
#include <iostream>
#include <queue>
#include <sstream>
#include <fstream>
#include <thread>
#include <mutex>
using namespace std;
 
mutex lockqueue;
mutex lock_td;
 
struct mark
{
    string name;
    string position; //Должность: уровень 1 - директор, уровень 2 - менеджер, уровень 3 - рабочий
    string datebirth;
};
struct TreeNode
{
    vector<TreeNode*> broth;
    vector<TreeNode*> children;
    mark value;
};
class TreeDictionary
{
    TreeNode *root;
public:
    TreeDictionary()
    {
        root =  NULL;
    }
    void insert(mark data){
        if(root == NULL){
            if(data.position == "директор"){
                root  = CreateNode(data);
            } else return;
        } else{
            if(data.position == "директор"){
                insert_broth(root, data);
            } else if(data.position == "менеджер"){
                if(root->broth.size() != 0)
                    insert_child(root->broth.back(), data);
                else
                    insert_child(root, data);
            } else if(data.position == "рядовой рабочий"){
                if(root->broth.size() != 0){
                    if((root->broth.back())->children.size() != 0)
                        insert_child((root->broth.back())->children.back(), data );
                } else{
                    if(root->children.size() != 0){
                        insert_child(root->children.back(), data);
                    }
                }
 
            }
 
        }
    }
    void insert_child(TreeNode * parent, mark n){
        TreeNode *temp = CreateNode(n);
        parent -> children.push_back(temp);
    }
    void insert_broth(TreeNode * broth, mark n){
        TreeNode *temp = CreateNode(n);
        broth -> broth.push_back(temp);
    }
    TreeNode * CreateNode(mark data){
        TreeNode *newNode = new TreeNode;
        newNode->value = data;
        return newNode;
    }
    void traveler(TreeNode * root, ostream &out){
        if(root == NULL)
            return;
        out << root->value.name << ',' << root->value.position << ',' << root->value.datebirth << '\n';
        for (int i = 0; i < root->children.size() && root->children[i]; i++)
            traveler(root->children[i], out);
    }
    void print(ostream& out){
        traveler(root, out);
        for (int i = 0; i < root->broth.size(); i++){
            traveler(root->broth[i],out);
        }
    }
    TreeNode * getroot() const{
        return root;
    }
 
};
void read_data(queue<string>& inputdata, TreeDictionary & tree){
    cout << "start1";
    while(!inputdata.empty()){
        mark man;
        stringstream ss(inputdata.front());
        getline(ss, man.name, ',');
        cout << man.name << endl;
        getline(ss, man.position, ',');
        getline(ss, man.datebirth);
        lockqueue.lock();
        inputdata.pop();
        lockqueue.unlock();
        lock_td.lock();
        tree.insert(man);
        lock_td.unlock();
    }
}
void write_data(string filename, TreeDictionary &tree){
    ofstream output(filename, ios::app);
    if(output.is_open()){
        cout << "start2";
        lock_td.lock();
        tree.print(output);
        lock_td.unlock();
    }
 
}
int main()
{
    queue<string> inputdata;
    TreeDictionary td;
    string infilename = "indata.txt";
    string outfilename = "outdata1.txt";
    auto td_a = ref(td);
    thread t1(read_data, ref(inputdata), td_a);
    thread t2(write_data, outfilename, td_a);
    ifstream input(infilename);
    if(input.is_open()){
        string data;
        while(getline(input, data)){
            lockqueue.lock();
            inputdata.push(data);
            //cout << inputdata.back();
            lockqueue.unlock();
            }
    }
    t1.join();
    t2.join();
    return 0;
}
Но вылазит ошибка сегментации. Вроде как все ломается в этой строке thread t2(write_data, outfilename, td_a);, но я не понимаю, почему не срабатывает. Буду рад любым советам\помощи
Rakf вне форума Ответить с цитированием
Старый 19.02.2019, 20:52   #2
JavaDoc
Пользователь
 
Регистрация: 15.12.2018
Сообщений: 16
По умолчанию

еслиб мы говорили о java то там такая ситуация - нужна синхронизация к неразделяемому ресурсу,ну или можно организовать доступ рид - врайт. нельзя одновременно с двух потоков долбить несинхронизированный объект есть вероятность наткнуться на несправеддливые данные. в джаве куча инструментов предусмотреноя честно говоря не знаю о каком языке идёт речь, но думаю что в синхронизаии проблема
JavaDoc вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как в c++ считать с файла строку и загнать ее в переменную? что-б можно было считать 3-ю 4-ю и тд строки отдельно НАЧИНАЮЩИЙ_ПРО Помощь студентам 1 15.03.2017 16:28
Считать массив чисел из файла и записать в другой файл два массива (Pascal ABC) Luka_Megurine Помощь студентам 0 20.12.2016 16:51
Как считать данные с файла и записать в массив? lord007 Visual C++ 0 05.05.2015 22:57
Записать и считать из файла Unicode строки WOLFak Общие вопросы Delphi 6 29.07.2012 21:27
FASM. Считать содержимое файла в строку и затем записать обратно в файл Zart Помощь студентам 0 19.04.2011 17:02