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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
#1

Vector и thread-safe - C++

08.07.2015, 02:41. Просмотров 1069. Ответов 27
Метки нет (Все метки)

Как лучше сделать свой класс типа контейнер шаблонный как вектор который будет ещё и thread-safe. Допустим есть обычный класс внутри вектор и надо так чтоб можно было работать кучей потоков с этим классом и не было ошибок доступа.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include <vector>
 
template<typename T>
class SafeArray()
{
private:
    std::vector< T*> Array;
 
public:
    SafeArray();
    ~SafeArray();
 
    /// как защитить мой контейнер вектор чтоб его потоки не порвали когда будут одновременно 
    /// добавлять удалять и так далее
    size_t SafeArray()::size(){ Array.size(); }
 
    void SafeArray()::push();
    void SafeArray()::clear(){ Array.clear(); }
    //.... и так далее разные функции.
}
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2015, 02:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Vector и thread-safe (C++):

thread-safe ли? - C++
Насколько я понимаю, для х32 процессоров атомарными операциями не являются те, что с double/long long, для х64 же и они атомарны. Если я...

Секундомер и thread-safe - C++
В моей программе мне нужно отслеживать время по секундам. Я сделал следующее: создал доп. поток, в котором вызывается методом с телом: ...

Thread-safe ли чтение структур? - C++
Собственно, безопасно ли нескольким потокам одновременно читать значение глобальной переменной, если она не влазит в примитивный тип?

Thread-safe smart pointer - C++
Нужно мне это для реализации COW механизма. В STL, насколько я понимаю, shared_ptr такого не может дать. Однако, покопавшись в...

Что такое thread safe? - C++
Всем добрый день! Вопрос, собственно, в имени темы.:) Что это такое? Я так понимаю, что переменная не меняет значения при...

error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Vector<int>::Vector<int>(void)" (?0?$Vector@H@@QAE@XZ) в функции _main - C++
//Vector.h #include &lt;iostream&gt; #include &lt;Windows.h&gt; #include &lt;climits&gt; #include &lt;vector&gt; #include &lt;stdlib.h&gt; #include &lt;fstream&gt;...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:10  [ТС] #16
у меня вопрос тогда эта писанина void emplace(Args&&... args) тоже будет работать?
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:12 #17
Должна работать.
0
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:13  [ТС] #18
а ты чем компилировал?
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:15 #19
gcc-5.1.0
0
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:16  [ТС] #20
у меня вопрос тогда нафига писать всякие мьюмексы и подобный маразм в программах которые неимоверно будет сложно поддерживать и развивать?
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:18 #21
Даже не знаю что тебе на это ответить. Программирование на С++ вообще сложное дело. Пиши на Java.
0
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:20  [ТС] #22
не я имею ввиду можно же использовать OMP там всё куда понятней
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:23 #23
Для меня OMP темный лес. Надо было сразу в теме указать что нужно на OMP.
0
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:34  [ТС] #24
конечный вариант
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <iostream>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>
#include <queue>
#include <algorithm>
#include <functional>
#include <utility>
 
template <typename T>
class threadsafe_queue
{
    mutable std::mutex mut;
    std::queue<T> data;
 
    bool has_el(std::queue<T> qu, T &&value) const
    {
        while (!qu.empty()) {
            if (value == qu.front()) return true;
            qu.pop();
        }
        return false;
    }
 
    bool add_unique_el(T &&t)
    {
        if (has_el(data, std::forward<T>(t)))
            return false;
        else {
            data.push(std::forward<T>(t));
            return true;
        }
    }
 
public:
    threadsafe_queue() = default;
    threadsafe_queue(threadsafe_queue const& other) = delete;
    threadsafe_queue & operator =(threadsafe_queue const& other) = delete;
 
    threadsafe_queue(threadsafe_queue && other) = default;
    threadsafe_queue & operator =(threadsafe_queue && other) = default;
 
    std::size_t size() const
    {
        std::lock_guard<std::mutex> locker(mut);
        return data.size();
    }
 
    void swap(threadsafe_queue & other) noexcept(noexcept(std::swap(data, other.data)))
    {
        using std::swap;
 
        std::lock_guard<std::mutex> locker(mut);
        swap(data, other.data);
    }
 
    bool push(T &&new_value)
    {
        std::lock_guard<std::mutex> locker(mut);
        return add_unique_el(std::forward<T>(new_value));
    }
 
    bool push(const T &new_value)
    {
        std::lock_guard<std::mutex> locker(mut);
        return add_unique_el(T(new_value));
    }
 
    void pop()
    {
        std::lock_guard<std::mutex> locker(mut);
        data.pop();
    }
 
    T& front()
    {
        std::lock_guard<std::mutex> locker(mut);
        if ( !data.empty() )
            return data.front();
    }
 
    T& back()
    {
        std::lock_guard<std::mutex> locker(mut);
        if ( !data.empty() )
            return data.back();
    }
 
    const T& front() const
    {
        std::lock_guard<std::mutex> locker(mut);
        if ( !data.empty() )
            return data.front();
    }
 
    const T& back() const
    {
        std::lock_guard<std::mutex> locker(mut);
        if ( !data.empty() )
            return data.back();
    }
 
    template< class... Args >
    void emplace(Args&&... args)
    {
        std::lock_guard<std::mutex> locker(mut);
        return add_unique_el(T(std::forward<Args>(args)...));
    }
 
    bool empty() const noexcept
    {
        std::lock_guard<std::mutex> locker(mut);
        return data.empty();
    }
 
    void print_queue(std::ostream& os = std::cout)
    {
        std::lock_guard<std::mutex> locker(mut);
        std::queue<T> temp(data);
 
        while (!temp.empty()) {
            os << temp.front() << " ";
            temp.pop();
        }
        os << std::endl;
    }
};
 
 
////////////////////////////////////////////////////////
 
void prepare_data(threadsafe_queue<int>& q)
{
    while(true)
    {
        for (int i = 0; i < 5; ++i)
        {
            q.push(i);
            q.push(i);
            q.push(i);
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}
 
void processing_data(threadsafe_queue<int>& q, int id)
{
    while(true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "Thread: " << id << ", val: "; 
q.print_queue();
    }
}
 
int main()
{
    threadsafe_queue <int> test;
 
    std::thread t_q1 (prepare_data, std::ref(test));
    std::thread t_q2 (prepare_data, std::ref(test));
    std::thread t_q3 (prepare_data, std::ref(test));
    std::thread t_q4 (prepare_data, std::ref(test));
    std::thread t_q5 (prepare_data, std::ref(test));
    std::thread t_q6 (prepare_data, std::ref(test));
    std::thread t_q7 (prepare_data, std::ref(test));
    std::thread t_q8 (prepare_data, std::ref(test));
    std::thread t1(processing_data, std::ref(test), 1);
    std::thread t2(processing_data, std::ref(test), 2);
 
    t_q1.join();
    t_q2.join();
    t_q3.join();
    t_q4.join();
    t_q5.join();
    t_q6.join();
    t_q7.join();
    t_q8.join();
 
    t1.join();
    t2.join();
 
    std::cout << "\n\nDone.\n";
}
gcc это типа ты как крот в консоле компилишь?)

Добавлено через 4 минуты
DiffEreD, ты не мог бы это дело откомпилировать и сюда exe скинуть поглядеть что же будет
0
DiffEreD
1430 / 767 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:43 #25
Пожалуйста.
0
Вложения
Тип файла: 7z 1.7z (227.3 Кб, 2 просмотров)
xEmpire
25 / 25 / 9
Регистрация: 07.12.2012
Сообщений: 169
Завершенные тесты: 1
09.07.2015, 16:27 #26
Ko, есть такая вещь, как std::thread::hardware_concurrency, которая может вернуть допустимое количество потоков, не теряя производительность (а может и не вернуть - вернуть 0 (вычислить значение не возможно))
C++
1
2
3
4
5
6
7
8
9
10
    while(true)
    {
        for (int i = 0; i < 5; ++i)
        {
            q.push(i);
            q.push(i);
            q.push(i);
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
Каким образом должен произойти возврат управления?
0
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
12.07.2015, 23:45  [ТС] #27
xEmpire да тут не важно просто это тест.
0
Avazart
Эксперт С++
7185 / 5359 / 280
Регистрация: 10.12.2010
Сообщений: 23,650
Записей в блоге: 17
13.07.2015, 17:00 #28
https://www.lektorium.tv/course/23050

Параллельное программирование


Добавлено через 5 минут
Ну и Уильямс Э. "Параллельное программирование на С++ в действии. Практика разработки многопоточных программ" - 2012
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.07.2015, 17:00
Привет! Вот еще темы с ответами:

Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>) - C++
Написал программу, которая создает вектор 'а' векторов 'b', вектора 'b' содержат 2 числа. Стало интересно, как нужно изменить программу...

Ошибка компиляции "no instance of constructor 'std::thread::thread' matches the argument list" - C++
Не могу сообразить почему возникает ошибка. У меня в классе есть метод, который должен работать в нескольких потоках одновременно. Вот он: ...

vector<Struct2{int,vector<struct1>}> или множественное наследование ... - C++
Здравствуйте! Помогите, пожалуйста. Есть такие данные: typedef struct { int x; int y; // координаты...

Ошибка [Linker error] undefined reference to `Vector::Vector(int)' - C++
Добрый день. Делал по методички, и почему-то валятся ошибки... файл lab9_main.cpp #include &lt;iostream&gt; #include &quot;Vector.h&quot; int...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
13.07.2015, 17:00
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru