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

Критические секции - C++

Восстановить пароль Регистрация
 
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
12.07.2013, 08:23     Критические секции #1
было так:
C++
1
2
3
4
5
6
7
8
9
10
class A {
    someType t;
public:
    void f1() {
        модификация t;
    }
    void f2() {
        модификация t;
    }
};
хочу так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A {
    someType t;
public:
    void f1() {
        критическая секция
        модификация t;
    }
    void f2() {
        критическая секция
        модификация t;
    }
    void f3() {
        критическая секция
        модификация t;
    }
};
Вот такая конструкция. Все три функции дергаются каждая из своего потока. Причем, f2 и f3 очень интенсивно, а f1 очень редко. При этом, если бы не было функции f1, то критические секции для f2 и f3 вообще не нужны, потому что логика внутри f2 и f3 устроена так, что конфликтов не возникает. Собственно, вопрос: как сделать так, чтобы при добавлении функции f1, у меня функции f2 и f3 выполнялись параллельно, пока нет входа в f1, а при входе в f1, естественно управление давалось бы либо функции f1 (причем у нее приоритет, она должна как можно быстрее отработать и уйти, и не тормозить параллельную работу f2 и f3) либо параллельная работа функций f2 и f3 (хотя в этот момент можно и не параллельно, не критично, так как f1 выполняется очень быстро).

Добавлено через 12 минут
И еще тут же вопрос. Правильно ли я понимаю вот это: http://vsokovikov.narod.ru/New_MSDN_...calsection.htm
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
someType f;
void f1 {
    EnterCriticalSection
    очень много гомнокода1 по модификации f
    очень много гомнокода2 по модификации f
    очень много гомнокода3 по модификации f
    LeaveCriticalSection
}
void f2 {
    EnterCriticalSection
    очень много гомнокода4 по модификации f
    очень много гомнокода5 по модификации f
    очень много гомнокода6 по модификации f
    LeaveCriticalSection
}
пока полностью не выполнится одна из секция, она не прервется и не отдаст управление второй? ну грубо говоря: выполняется очень много гомнокода1 по модификации f, тот он локается и выполняется очень много гомнокода4 по модификации f, тут локается он и возвращается к очень много гомнокода1 по модификации f ??
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
12.07.2013, 10:27     Критические секции #2
Цитата Сообщение от Kukurudza Посмотреть сообщение
При этом, если бы не было функции f1, то критические секции для f2 и f3 вообще не нужны, потому что логика внутри f2 и f3 устроена так, что конфликтов не возникает.
1. А вот это, кстати, отнюдь не факт. Если происходит модификация некоей переменной из разных потоков без синхронизации, то результаты могут быть очень-очень непредсказуемыми. (Более того, на разных компиляторах результат может быть разным!) В клиническом случае это может приводить к появлению в программе "плавающей" ошибки, которая проявляется только на оборудовании заказчика раз в месяц в и непредсказуемое время в зависимости от фазы Луны и положения кошкиного хвоста. Ситуация становится особенно пикантной на современных многоядерных машинах :-)

Если синхронизация критической секцией не устраивает, посмотри на заголовок <atomic>.

2. А вот так синхронизировать критической секцией
C++
1
2
3
4
5
6
7
void f1 {
    EnterCriticalSection
    очень много гомнокода1 по модификации f
    очень много гомнокода2 по модификации f
    очень много гомнокода3 по модификации f
    LeaveCriticalSection
}
нельзя. Причина: если паче чаяния в каком-то из блоков "очень много гомнокодаX по модификации f" вдруг вылетит исключение, - вуаля! критсекция останется навеки заблокированной, и никакая другая функция к выполнению этого "гомнокода" уже не придет никогда. Рано или поздно программа впадет в ступор. Рекомендую использовать объект-синхронизатор, владеющий критической секцией, и реализующий идиому RAII.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
12.07.2013, 10:47     Критические секции #3
А почему бы не воспользоваться обычными мютексами?:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A {
   int t = 0;
   mutable std::recursive_mutex m;
public:
    void f1() {
       std::lock_guard<std::recursive_mutex> locker(m);
       ++t;
    }
    void f2() {
       std::lock_guard<std::recursive_mutex> locker(m);
       if (t == 2)
          f1();
    }
    void f3() {
       std::lock_guard<std::recursive_mutex> locker(m);
       if (t == 1)
          f1();
    }
};
Kukurudza
105 / 86 / 6
Регистрация: 29.08.2012
Сообщений: 539
12.07.2013, 11:51  [ТС]     Критические секции #4
Цитата Сообщение от CheshireCat Посмотреть сообщение
Причина: если паче чаяния в каком-то из блоков "очень много гомнокодаX по модификации f" вдруг вылетит исключение, - вуаля! критсекция останется навеки заблокированной, и никакая другая функция к выполнению этого "гомнокода" уже не придет никогда
эти вызовы обернуты в объект, поэтому вызовется деструктор. я не стал просто объект приводить для краткости. а, ну собственно как у вас и написано:
Цитата Сообщение от CheshireCat
Рекомендую использовать объект-синхронизатор, владеющий критической секцией, и реализующий идиому RAII.
Цитата Сообщение от DiffEreD Посмотреть сообщение
А почему бы не воспользоваться обычными мютексами?
ща повкуриваю.
Yandex
Объявления
12.07.2013, 11:51     Критические секции
Ответ Создать тему
Опции темы

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