Форум программистов, компьютерный форум CyberForum.ru

Контейнер unordered_map, содержащий потоки - C++

Восстановить пароль Регистрация
 
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 01:36     Контейнер unordered_map, содержащий потоки #1
постановка задачи:
есть некий класс Item
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Item
{
private:
    int id;
    string text;
public:
    Item() 
    {
        text = "default";
        id = -1;
    }
    void SetText(string text) { this->text = text; }
    void SetId(int id) { this->id = id; }
    string GetText() { return text; }
    int GetId() { return id; }
    ~Item() {}
};
есть класс ItemSubSystem который имеет vector объектов Item* и unordered_map, где ключ int а значение Item*. Класс имеет два метода - один выводит список элементов вектора, другой - модифицирует элементы map. Так как что вектор что map содержат указатели на одни и те же объекты - то есть изменение значений полей элемента Item* в map приводит к изменению значений в vector.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class ItemSubSystem
{
private:
    vector<Item*> toDraw;
    boost::unordered_map<int, Item*> controllerMap;
    int size;
public:
    ItemSubSystem() {};
    void InitAll()
    {
        size = 10;
        for(int i = 0; i < size; i++)
        {
            Item *it = new Item();
            it->SetId(i);
            string text = "item-" + boost::lexical_cast<string>(i);
            it->SetText(text);
            toDraw.push_back(it);
            controllerMap.insert(std::make_pair(i, it));
        }
    }
    void DrawAll() {
        BOOST_FOREACH(auto i, toDraw)
        {
            cout<<";"<<i->GetText();
        }
        cout<<endl;
    }
    void ModifyAll()
    {
        for(int i = 0; i < size; i++)
        {
            Item *it = controllerMap[i];
            int t = it->GetId();
            it->SetId(++t);
            string text = "item-" + boost::lexical_cast<string>(t);
            it->SetText(text);
        }
    }
    ~ItemSubSystem() 
    {
        BOOST_FOREACH(auto i, toDraw) delete i;
        toDraw.clear();
 
        BOOST_FOREACH(auto& i, controllerMap) delete i.second;
        controllerMap.clear();
    }
};
Необходимо чтобы в одном потоке вызывался метод drawAll, который бы выводил элементы вектора, а в другом - изменялись значения в map.

изначательно я создавал потоки в функции main. я создал две функции потоков
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void DrawThread()
{
    for(;;)
    {
        try 
        {
            boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
            items->DrawAll();
        }
        catch(boost::thread_interrupted&)
        {
            cout<<"Draw thread is stopped"<<endl;
            return;
        }
    }   
};
 
void ModifyThread()
{
    for(;;)
    {
        try 
        {
            boost::this_thread::sleep(boost::posix_time::milliseconds(15000));
            items->ModifyAll();
        }
        catch(boost::thread_interrupted&)
        {
            cout<<"Modify thread is stopped"<<endl;
            return;
        }
    }
};
где items
C++
1
ItemSubSystem *items;
Все работало если создавал потоки в main и там же останавливал.

Но потом я решил создать класс, который содержал бы map, где ключ - идентификатор потока, а значение - собственно сам поток. класс должен был позволить добавлять и останавливать/удалять потоки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ItemThreadingController
{
private:
    boost::unordered_map<long int, boost::thread> controllerMap;
    long int id;
public:
    ItemThreadingController() 
    {
        id = -1;
    }
    int AddThread(void (*func)())
    {
        boost::thread t(func);
        id++;
        controllerMap.insert(std::make_pair(id, t));
        return id;
    }
    void StopThread(long int id)
    {
        controllerMap[id].interrupt();
        controllerMap[id].join();
        controllerMap.erase(id);
        cout<<"Thread "<<id<<"has stopped and erased!"<<endl;
    }
    ~ItemThreadingController() {};
};
проблема в том, что если я оставляю код без изменений - то выдаётся ошибка при сборке
Код
13	IntelliSense: #error directive: "Incompatible build options"	111
Error	1	error C2248: 'boost::thread::thread' : cannot access private member declared in class 'boost::thread'	247
но если я закомментирую строку
C++
1
2
3
4
5
6
7
int AddThread(void (*func)())
    {
        boost::thread t(func);
        id++;
        //controllerMap.insert(std::make_pair(id, t));
        return id;
    }
то собирается без ошибок.

функция main выглядит так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(int argc, char** argv)
{
    items = new ItemSubSystem();
    items->InitAll();
 
    ItemThreadingController *threads = new ItemThreadingController();
    int t1 = threads->AddThread(DrawThread);
    int t2 = threads->AddThread(ModifyThread);
 
    boost::this_thread::sleep(boost::posix_time::milliseconds(50000));
    threads->StopThread(t1);
    threads->StopThread(t2);
 
    return 0;
}
почему возникает ошибка?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.01.2014, 01:36     Контейнер unordered_map, содержащий потоки
Посмотрите здесь:

std::unordered_map и много-поточность C++
C++ Работа с unordered_map
Hash_map unordered_map C++
C++ Доступ к элементам unordered_map
Поиск по нескольким unordered_map C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 01:47     Контейнер unordered_map, содержащий потоки #2
Artishok, boost::thread не поддерживает копирование. Если есть поддержка C++11, то можно использовать move
C++
1
controllerMap.insert(std::make_pair(id, std::move(t)));
Если нет, то можно хранить указатель на thread, например boost::shared_ptr<boost::thread>
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
26.01.2014, 01:48     Контейнер unordered_map, содержащий потоки #3
del
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 01:56  [ТС]     Контейнер unordered_map, содержащий потоки #4
Цитата Сообщение от gray_fox Посмотреть сообщение
Artishok, boost::thread не поддерживает копирование. Если есть поддержка C++11, то можно использовать move
C++
1
controllerMap.insert(std::make_pair(id, std::move(t)));
Если нет, то можно хранить указатель на thread, например boost::shared_ptr<boost::thread>
это получается нужно сделать метод таким
C++
1
2
3
4
5
6
7
int AddThread(void (*func)())
    {
        boost::shared_ptr<boost::thread> p (new boost::thread(func));
        id++;
        controllerMap.insert(std::make_pair(id, p));
        return id;
    }
а контейнер таким
C++
1
boost::unordered_map<long int, boost::shared_ptr<boost::thread>> controllerMap;
?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 02:02     Контейнер unordered_map, содержащий потоки #5
Artishok, именно. Либо, что бы не возиться с умными указателями, можно использовать boost::ptr_unordered_map как вариант.
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:12  [ТС]     Контейнер unordered_map, содержащий потоки #6
Цитата Сообщение от gray_fox Посмотреть сообщение
Artishok, именно. Либо, что бы не возиться с умными указателями, можно использовать boost:tr_unordered_map как вариант.
Ну так у меня по сути не будет обращений к элементам использующих один и тот же элемент shared_ptr так что можно и так оставить.

разве что я так понимаю нужно в деструктор добавить

C++
1
2
3
4
5
~ItemThreadingController() 
    {
        BOOST_FOREACH(auto& i, controllerMap) 
            i.second.reset();
    };
?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 02:18     Контейнер unordered_map, содержащий потоки #7
Цитата Сообщение от Artishok Посмотреть сообщение
разве что я так понимаю нужно в деструктор добавить
не надо, shared_ptr в своём деструкторе вызовет delete, умный же)
Цитата Сообщение от Artishok Посмотреть сообщение
Ну так у меня по сути не будет обращений к элементам использующих один и тот же элемент shared_ptr так что можно и так оставить.
Ну ptr_unordered_map поэффективней должен быть, как минимум он не занимается подсчётом ссылок, в отличие от shared_ptr. Я правда не знаю, в какой версии boost этот контейнер добавили.
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:18  [ТС]     Контейнер unordered_map, содержащий потоки #8
Цитата Сообщение от gray_fox Посмотреть сообщение
не надо, shared_ptr в своём деструкторе вызовет delete, умный же)

Ну ptr_unordered_map поэффективней должен быть, как минимум он не занимается подсчётом ссылок, в отличие от shared_ptr. Я правда не знаю, в какой версии boost этот контейнер добавили.
ну у меня 1_55_0 так что он должен быть точно
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 02:26     Контейнер unordered_map, содержащий потоки #9
Так то можно просто хранить голые указатели в unordered_map, в деструкторе вызывать delete )

Добавлено через 7 минут
В принципе, если учесть, что ItemThreadingController нельзя копировать, то наверное можно использовать и auto_ptr. Если копирировать можно, то проще с shared_ptr.
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:31  [ТС]     Контейнер unordered_map, содержащий потоки #10
Цитата Сообщение от gray_fox Посмотреть сообщение
Так то можно просто хранить голые указатели в unordered_map, в деструкторе вызывать delete )

Добавлено через 7 минут
В принципе, если учесть, что ItemThreadingController нельзя копировать, то наверное можно использовать и auto_ptr. Если копирировать можно, то проще с shared_ptr.
всмысле нельзя копировать? у меня это просто такой примитивный по сути менеджер потоков в программе. прототип его если быть более точным. он такой один будет только.

как добавить тогда элемент в ptr_unordered_map?
C++
1
boost::ptr_unordered_map<int, boost::thread> controllerMap;
я пытаюсь и так
C++
1
2
3
4
5
boost::thread t(func);
        std::auto_ptr<boost::thread> tp(&t);
        id++;
        controllerMap.insert(std::make_pair(id, tp));
        return id;
и по-другому...ругается.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 02:36     Контейнер unordered_map, содержащий потоки #11
Цитата Сообщение от Artishok Посмотреть сообщение
всмысле нельзя копировать?
В прямом, если не подразумевается такое
C++
1
ItemThreadingController copy(original);
либо
C++
1
copy = original;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2014, 02:40     Контейнер unordered_map, содержащий потоки
Еще ссылки по теме:

C++1z — std::unordered_map::try_emplace — объясните работу функции C++
C++ Выборка map/unordered_map по значению
Создание вложенного unordered_map C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Artishok
ЧакЭ одобряЭ
 Аватар для Artishok
277 / 276 / 32
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:40  [ТС]     Контейнер unordered_map, содержащий потоки #12
Цитата Сообщение от gray_fox Посмотреть сообщение
В прямом, если не подразумевается такое
C++
1
ItemThreadingController copy(original);
либо
C++
1
copy = original;
а понятно...
Yandex
Объявления
26.01.2014, 02:40     Контейнер unordered_map, содержащий потоки
Ответ Создать тему
Опции темы

Текущее время: 00:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru