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

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

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

Vector и thread-safe - C++

08.07.2015, 02:41. Просмотров 976. Ответов 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(); }
    //.... и так далее разные функции.
}
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:18     Vector и thread-safe #21
Даже не знаю что тебе на это ответить. Программирование на С++ вообще сложное дело. Пиши на Java.
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:20  [ТС]     Vector и thread-safe #22
не я имею ввиду можно же использовать OMP там всё куда понятней
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:23     Vector и thread-safe #23
Для меня OMP темный лес. Надо было сразу в теме указать что нужно на OMP.
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
09.07.2015, 15:34  [ТС]     Vector и thread-safe #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 скинуть поглядеть что же будет
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
09.07.2015, 15:43     Vector и thread-safe #25
Пожалуйста.
Вложения
Тип файла: 7z 1.7z (227.3 Кб, 2 просмотров)
xEmpire
23 / 23 / 9
Регистрация: 07.12.2012
Сообщений: 169
Завершенные тесты: 1
09.07.2015, 16:27     Vector и thread-safe #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));
    }
Каким образом должен произойти возврат управления?
Ko
-65 / 5 / 0
Регистрация: 23.12.2011
Сообщений: 246
12.07.2015, 23:45  [ТС]     Vector и thread-safe #27
xEmpire да тут не важно просто это тест.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.07.2015, 17:00     Vector и thread-safe
Еще ссылки по теме:

C++ Не работает функция sort (vector, vector)
Сортировка vector<vector<int>> C++
Thread-safe smart pointer C++
C++11. thread, mutex, thread-safety C++
C++ Ошибка компиляции "no instance of constructor 'std::thread::thread' matches the argument list"

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

Или воспользуйтесь поиском по форуму:
Avazart
7046 / 5223 / 259
Регистрация: 10.12.2010
Сообщений: 22,966
Записей в блоге: 17
13.07.2015, 17:00     Vector и thread-safe #28
https://www.lektorium.tv/course/23050

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


Добавлено через 5 минут
Ну и Уильямс Э. "Параллельное программирование на С++ в действии. Практика разработки многопоточных программ" - 2012
Yandex
Объявления
13.07.2015, 17:00     Vector и thread-safe
Ответ Создать тему
Опции темы

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