Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767

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

26.01.2014, 01:36. Показов 1367. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
постановка задачи:
есть некий класс 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() {};
};
проблема в том, что если я оставляю код без изменений - то выдаётся ошибка при сборке
Code
1
2
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;
}
почему возникает ошибка?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.01.2014, 01:36
Ответы с готовыми решениями:

Контейнер map содержащий векторы
Доброго времени суток уважаемые! Подскажите пожалуйста можно ли организовать map&lt;vector, vector&gt; и правильно ли так поступать? ...

Класс-контейнер на основе бинарного дерева, содержащий квадраты,
Необходимо спроектировать и запрограммировать на языке C++ класс-контейнер (бинарное дерево), содержащее квадрат. Класс-контейнер...

Работа с unordered_map
очень прошу помочь! имеется вот такой код: struct LOCATION { DATA_TYPE type; unsigned int pos; }; typedef...

11
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
26.01.2014, 01:47
Artishok, boost::thread не поддерживает копирование. Если есть поддержка C++11, то можно использовать move
C++
1
controllerMap.insert(std::make_pair(id, std::move(t)));
Если нет, то можно хранить указатель на thread, например boost::shared_ptr<boost::thread>
1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
26.01.2014, 01:48
del
0
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 01:56  [ТС]
Цитата Сообщение от 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;
?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
26.01.2014, 02:02
Artishok, именно. Либо, что бы не возиться с умными указателями, можно использовать boost::ptr_unordered_map как вариант.
1
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:12  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
Artishok, именно. Либо, что бы не возиться с умными указателями, можно использовать boost:tr_unordered_map как вариант.
Ну так у меня по сути не будет обращений к элементам использующих один и тот же элемент shared_ptr так что можно и так оставить.

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

C++
1
2
3
4
5
~ItemThreadingController() 
    {
        BOOST_FOREACH(auto& i, controllerMap) 
            i.second.reset();
    };
?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
26.01.2014, 02:18
Цитата Сообщение от Artishok Посмотреть сообщение
разве что я так понимаю нужно в деструктор добавить
не надо, shared_ptr в своём деструкторе вызовет delete, умный же)
Цитата Сообщение от Artishok Посмотреть сообщение
Ну так у меня по сути не будет обращений к элементам использующих один и тот же элемент shared_ptr так что можно и так оставить.
Ну ptr_unordered_map поэффективней должен быть, как минимум он не занимается подсчётом ссылок, в отличие от shared_ptr. Я правда не знаю, в какой версии boost этот контейнер добавили.
1
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:18  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
не надо, shared_ptr в своём деструкторе вызовет delete, умный же)

Ну ptr_unordered_map поэффективней должен быть, как минимум он не занимается подсчётом ссылок, в отличие от shared_ptr. Я правда не знаю, в какой версии boost этот контейнер добавили.
ну у меня 1_55_0 так что он должен быть точно
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
26.01.2014, 02:26
Так то можно просто хранить голые указатели в unordered_map, в деструкторе вызывать delete )

Добавлено через 7 минут
В принципе, если учесть, что ItemThreadingController нельзя копировать, то наверное можно использовать и auto_ptr. Если копирировать можно, то проще с shared_ptr.
1
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:31  [ТС]
Цитата Сообщение от 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;
и по-другому...ругается.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
26.01.2014, 02:36
Цитата Сообщение от Artishok Посмотреть сообщение
всмысле нельзя копировать?
В прямом, если не подразумевается такое
C++
1
ItemThreadingController copy(original);
либо
C++
1
copy = original;
0
ЧакЭ одобряЭ
 Аватар для Artishok
285 / 284 / 86
Регистрация: 27.12.2009
Сообщений: 1,767
26.01.2014, 02:40  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
В прямом, если не подразумевается такое
C++
1
ItemThreadingController copy(original);
либо
C++
1
copy = original;
а понятно...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.01.2014, 02:40
Помогаю со студенческими работами здесь

Unordered_set и unordered_map
Добрый день. Объясните простыми словами отличия этих контейнеров от set и map. Не нашел простого объяснения на русском языке)

Hash_map unordered_map
class P{ public: int x, y; friend bool operator&lt; (const P u, const P v) { if(u.x &lt; v.x) { return true; } else...

Реализация контейнера unordered_map
Привет. Не могу найти реализацию этого контейнера. Помогите ссылкой или кодом.

Доступ к элементам unordered_map
struct Foo { int a,b,c; }; std::unordered_map&lt;std::pair&lt;int32_t, int32_t&gt;, std::unordered_map&lt;uint32_t, Foo&gt;&gt; bar; int...

Как реализован unordered_map?
Собственно, интересна именно практическая сторона вопроса, как реализуется идеальное хеширование за O(1) в среднем ясно, об этом можно...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru