Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
Bushmeister
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
#1

Один mutex на несколько функций

19.04.2016, 13:56. Просмотров 1109. Ответов 50
Метки нет (Все метки)

Есть три функции, которые могут работать с одним вектором в одно и то же время из разных потоков. Можно ли использовать один мьютекс на эти несколько функций, чтобы не синхронизировать работу 3-х мьютексов?
Код чисто для примера, чтобы было понятно, чего я хочу
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
mutex m;
vector<int> vec;
 
void Add(int i)
{
    m.lock();
        try
        {
            vec.push_back(i);
        }
        catch(exception ex)
        {
            m.unlock();
            throw ex;
        }
    m.unlock(); //все ок.
}
 
void Remove(int i)
{
    m.lock()
        try
        {
            //находим с помощью итераторов индекс с значением i и erasим его
            ...
        }
        catch(exception ex)
        {
            //если произойдет ошибка, анлокним мьютекс, чтобы другие функции могли
            //продолжить работу, а ошибку пробросим выше.
            m.unlock();
            throw ex;
        }
    m.unlock(); //все ок.
}
 
void Read(int index)
{
    m.lock()
        try
        {
            for (int i=0; i<vec.size(); i++)
            {
                if (i==index)
                {
                    vec[i].....
                    //шаманим со значением по индексу...
                }
            }
        }
        catch(exception ex)
        {
            m.unlock();
            throw ex;
        }
    m.unlock(); //все ок.
}
2
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.04.2016, 13:56
Ответы с готовыми решениями:

Разбить на несколько функций
Доброго времени суток, подскажите пожалуйста, нужно разбить одну большую...

Реализовать несколько функций
Реализовать несколько функций с различным числом аргументов и типами...

Добавить несколько функций
привет всем) вот есть код на С++ в консольном приложении VS 2008 - калькулятор...

Объединить несколько функций в одну
Подскажите, пожалуйста! Фрагменты 1 и 2 нужно забрать в одну функцию, фр. 3 и 4...

Несколько функций в одной программе
Проблема такая. Пишу программу, хочу, чтобы при выборе определенного номера...

50
eagl69
5 / 10 / 7
Регистрация: 12.10.2011
Сообщений: 505
19.04.2016, 14:22 #2
Ставь мьютекс при обращении к данному вектору в любой функции при этом пока не разблокируешь вторая функция при обращении к данному вектору будет ждать... Но надо следить за данными в этом векторе
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 15:45 #3
Только надо учитывать, что mutex не имеет очереди.
0
Bushmeister
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
19.04.2016, 16:00  [ТС] #4
Цитата Сообщение от nmcf Посмотреть сообщение
Только надо учитывать, что mutex не имеет очереди.
Разве? А кто тогда имеет?
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 16:04 #5
Я имею в виду, что управление получает не обязательно первый, кто обратился (когда он был занят).
0
Bushmeister
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
19.04.2016, 16:17  [ТС] #6
Цитата Сообщение от nmcf Посмотреть сообщение
Я имею в виду, что управление получает не обязательно первый, кто обратился (когда он был занят).
В моих планах это не критично. Но все же существует мьютексы, которые контролируют кто первый получит управление?
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 19:06 #7
Мьютекс всего один.
0
Bushmeister
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
19.04.2016, 21:38  [ТС] #8
Цитата Сообщение от nmcf Посмотреть сообщение
Мьютекс всего один.
Ну как это один? Я думал может ещё какие есть, но нет так нет.
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 21:50 #9
Они все одинаковые в этом плане. Там надо другие приёмы программирования применять, если нужна очередь.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4423 / 2394 / 664
Регистрация: 18.10.2014
Сообщений: 4,048
19.04.2016, 21:52 #10
Цитата Сообщение от Bushmeister Посмотреть сообщение
Можно ли использовать один мьютекс на эти несколько функций
Странный вопрос какой-то. В своем самом базовом применении мьютекс привязан к разделяемому ресурсу, а не к пользователям этого ресурса. Один ресурс - один мьютекс. В данном случае, если разделяемым ресурсом является некой вектор, то разумеется речь идет сразу, по-умолчанию именно об одном мьютексе.

Поэтому откуда может даже возникнуть такой вопрос как "можно ли использовать один мьютекс" мне в упор не ясно. Разумеется, можно. А как еще?

Цитата Сообщение от Bushmeister Посмотреть сообщение
чтобы не синхронизировать работу 3-х мьютексов?
Это как это??? И зачем???
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 21:54 #11
TheCalligrapher, ты лучше про очередь просвети.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4423 / 2394 / 664
Регистрация: 18.10.2014
Сообщений: 4,048
19.04.2016, 21:56 #12
Цитата Сообщение от nmcf Посмотреть сообщение
про очередь просвети
А откуда вообще взялся вопрос об "очереди"? Оно кому-то надо? Если надо - то пусть объясняют, что именно им надо.
0
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 22:05 #13
От меня взялся. Я просто сказал, что мьютекс не обладает очередью. Как это быстрее и проще реализовать, знаешь?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4423 / 2394 / 664
Регистрация: 18.10.2014
Сообщений: 4,048
19.04.2016, 22:11 #14
Цитата Сообщение от nmcf Посмотреть сообщение
Как это быстрее и проще реализовать
Что именно реализовать?

В параллельном программировании очередность прихода конкурирующих потоков на mutex - это типичный race condition. Правильно реализованный код не может полагаться на специфические проявления race conditions, т.е. на очередность прихода потоков на mutex. Другими словами - это не нужно даже пытаться реализовывать, ибо завязанность на такую очередность является грубой ошибкой дизайна, которая приведет только к проблемам в будущем. Такая очередь просто никому не нужна.

Но это общие слова в ответ на нечеткий вопрос.

Если вы говорите о чем-то другом - то выражайтесь детальнее, что за "очередь" вам нужна.
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
19.04.2016, 22:28 #15
Лучший ответ Сообщение было отмечено rikimaru2013 как решение

Решение

Bushmeister,
Мне просто больно смотреть и не написать следующее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
std::mutex m;
std::vector<int> vec;
 
void Add(int i)
{
    std::lock_guard<std::mutex> lock(m);
    vec.push_back(i);
}
 
void Remove(int i)
{
    std::lock_guard<std::mutex> lock(m);
    vec.erase(std::remove(std::begin(vec), std::end(vec), i), std::end(vec));
}
 
void Read(int index)
{
    std::lock_guard<std::mutex> lock(m);
    for (auto& i : vec)
    {
        //шаманим со значением по индексу...
    }
}
2
nmcf
6265 / 5575 / 2534
Регистрация: 14.04.2014
Сообщений: 23,468
19.04.2016, 22:56 #16
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Такая очередь просто никому не нужна.
Я не понял, при чём тут race condition. Нужно просто, чтобы потоки, получали управление в том порядке в каком они повисли на мьютексе - FIFO.
По поводу нужности или ненужности - бывали тут темы, в которых просили реализовать именно такое поведение, например, чтобы потоки выполняли обработку строго друг за другом.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4423 / 2394 / 664
Регистрация: 18.10.2014
Сообщений: 4,048
19.04.2016, 23:40 #17
Цитата Сообщение от nmcf Посмотреть сообщение
Я не понял, при чём тут race condition. Нужно просто, чтобы потоки, получали управление в том порядке в каком они повисли на мьютексе - FIFO.
Если несколько потоков конкурируют за один mutex, то порядок их прихода на этот mutex - это просто ярчайший, хрестоматийнейший пример "гонки".

Цитата Сообщение от nmcf Посмотреть сообщение
в которых просили реализовать именно такое поведение, например, чтобы потоки выполняли обработку строго друг за другом.
Потоки, ждущие одного и тот же mutex, и так будут выполнять обработку "строго друг за другом". А вот требовать того, чтобы это "строго друг за другом" делалось в том же порядке, к котором потоки прибыли на ожидание - это уже к mutex никакого отношения не имеет. Сама фундаментальная идея mutex в самой своей основе предполагает, что порядок входа никакого значения не имеет. Ибо порядок прихода на ожидание - это "гонка".

Если кто-то такого просил - флаг им в руки, но в общем случае это бессмысленная просьба - попытка душить симптомы проблемы, вместо того, чтобы решать саму проблему. Поведение программы не должно зависеть от результатов "гонки". Кто-то "просил" этого? Ну так скажите им, чтобы перестали "просить".
2
warhast
19 / 19 / 4
Регистрация: 02.02.2014
Сообщений: 74
20.04.2016, 09:27 #18
Гонки тут ни при чем, речь о свойстве инструментов синхронизации. И стандарт в этом отношении ничего не требует, так что если в некоторой системе родной mutex окажется fair - то и std::mutex в ней будет fair.

По реализации - см. TBB от Intel, queuing_mutex, например.
0
Bushmeister
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
20.04.2016, 10:21  [ТС] #19
Ой, вот только не надо тут пальцы гнуть, если ещё кто-то не вникал в тему с мьютексами и знает их поверхностно, без практики. Похоже, придется напомнить, что это раздел для начинающих в C++. Для вас "странные вопросы" - абсолютно нормальные, логичные для тех, кто ещё не работал с этим серьезно и желает получить правильное решение, чтобы потом не наступать на грабли.
Цитата Сообщение от Nosey Посмотреть сообщение
Bushmeister,
Мне просто больно смотреть и не написать следующее:
Ну что поделать. В различных статьях, в которых я смотрел применение и работу мьютекса, во многих случаях использовали lock/unlock, а не lock_guard. Теперь-то жить стало проще)
Цитата Сообщение от Nosey Посмотреть сообщение
for (auto& i : vec)
Руки никак не доходили для изучения таких циклов. Видимо настало время)
0
Nosey
1350 / 401 / 144
Регистрация: 22.10.2014
Сообщений: 863
Завершенные тесты: 2
20.04.2016, 10:37 #20
Цитата Сообщение от Bushmeister Посмотреть сообщение
Ой, вот только не надо тут пальцы гнуть
Я ни коем образом не гнул, извиняюсь если так вышло ) Я лишь хотел подсказать куда копать дальше.
Цитата Сообщение от Bushmeister Посмотреть сообщение
Ну что поделать. В различных статьях, в которых я смотрел применение и работу мьютекса, во многих случаях использовали lock/unlock, а не lock_guard.
И это в общем отлично.
Так что как дочитаете, милости прошу:
http://en.cppreference.com/w/cpp/thread
и следом:
http://www.boost.org/doc/libs/1_60_0/doc/html/thread/
1
20.04.2016, 10:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.04.2016, 10:37

Нужно реализовать несколько функций
// копирует source в destination и возвращает указатель на destination char*...

Несколько функций - активна только одна
Вообщем есть несколько функций? int Fun1,Fun2,Fun3,Fun4; if(Fun1){Действие}...

Объединить несколько циклов в один
Здравствуйте! Соорудил небольшую систему для прохода по одномерному массиву с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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