С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
2 / 2 / 0
Регистрация: 23.01.2013
Сообщений: 23

Архитектура многопоточного приложения

07.03.2015, 20:27. Показов 3129. Ответов 16

Студворк — интернет-сервис помощи студентам
Добрый вечер!
Подскажите правильно ли я использую критическую секцию:
Вне всех форм и классов объявляю
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TCriticalSection *p_cs = new TCriticalSection;
 
unsigned int myThread::get_count(){
    unsigned int zn;
    p_cs->Acquire(); // lock out other threads
    zn = this->count;
    p_cs->Release();
    return zn;
} 
 
void __fastcall myThread::Execute(){
    for(unsigned int i=0;i<max;i++)
        this->count++;      
}
и в где-то в потоке VCL
C++
1
2
3
myThread * mth = new myThread(true);
 
unsigned int = mth->get_count();
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.03.2015, 20:27
Ответы с готовыми решениями:

Ошибка "в указанном dsn архитектура драйвера и архитектура приложения"
Вот такая ошибка при нажатии на кнопку &quot;Проверить соединение&quot; Я прочитал, что это возможно из за того, что моя система 64, а...

Пример простого многопоточного приложения
Добрый день. Пытаюсь реализовать пример из книги. Итак, интерфейсный модуль, созданный мастером поточных объектов. В объявление...

Реализовать выход из многопоточного приложения при нажатии сочетания клавиш "Ctrl+С"
Добрый день! Подскажите пжл, как реализоввать выход с многопоточного(консольного) приложения по обработке нажатия клавишь ctrl+c(при этом...

16
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
07.03.2015, 20:43
C++
1
2
3
4
5
6
7
8
9
void __fastcall myThread::Execute()
{
   for(unsigned int i=0;i<max;i++)
  {
       p_cs->Acquire(); // вот эти две строчки
       this->count++;
       p_cs->Release();  // нужно добавить
  }
}
Или проще: не использовать критическую секцию, а объявить переменную count с модификатором volatile:
C++
1
volatile unsigned int count;
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.03.2015, 23:31
Лучший ответ Сообщение было отмечено Убежденный как решение

Решение

Цитата Сообщение от kzru_hunter Посмотреть сообщение
Или проще: не использовать критическую секцию, а объявить переменную count с модификатором volatile:
Не дает гарантий.

Правильно использовать InterlockedIncrement() (и другие InterlockedXXX- функции).
Ну и есть еще boost::atomic и std::atomic

Добавлено через 7 минут
http://wm-help.net/books-onlin... 64-27.html
2
2 / 2 / 0
Регистрация: 23.01.2013
Сообщений: 23
08.03.2015, 09:08  [ТС]
а есть какой-то простой доступ к полям класса TThread? Вот из TThread к основному потоку VCL есть: метод Synchronize(). как-то не верится что ребята из Borland ничего такого не придумали...
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.03.2015, 09:38
Цитата Сообщение от Avazart Посмотреть сообщение
Не дает гарантий.
Да, к сожалению не даёт, не знал. Об этом узнал узнал из stackoverflow:
Using volatile won't help when you need to increment - because the read and the write are separate instructions. Another thread could change the value after you've read but before you write back.
Надеюсь, только из-за этого? Если так, то в данном примере использование volatile допустимо, т.к. один поток только записывает в переменную, а другой только считывает. К сожалению это допустимо до тех пор, пока логика работы с переменной не изменится.
P.S. статью ещё не читал - нету времени.
0
2 / 2 / 0
Регистрация: 23.01.2013
Сообщений: 23
08.03.2015, 12:27  [ТС]
Avazart , большое спасибо за ссылку!

Добавлено через 2 часа 30 минут
подытоживая вышесказанное:
для безопасного доступа к полям класса TThread надо сделать класс обертку с критическими секциями
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TCriticalSection *p_cs = new TCriticalSection;
class dataThread{
  unsigned int data ;
 
  public:
    unsigned int get_count(){
        unsigned int zn;
        p_cs->Acquire();
            zn = this->data;
        p_cs->Release();
        return zn;
    }
 
    void set_count(const unsigned int & zn){
        p_cs->Acquire();
            this->data = zn;
        p_cs->Release();
    }
};
правильно я понял?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.03.2015, 14:21
Цитата Сообщение от kzru_hunter Посмотреть сообщение
P.S. статью ещё не читал - нету времени.
Цитата Сообщение от Alex9999 Посмотреть сообщение
правильно я понял?
Походу я зря ссылки кидал.

Добавлено через 40 минут
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
class CriticalSection
{
public:
  CriticalSection()  { InitializeCriticalSection(&cs_); };
  ~CriticalSection() { DeleteCriticalSection(&cs_); };
  void enter()       { EnterCriticalSection(&cs_);}
  bool tryEnter()    { return  TryEnterCriticalSection(&cs_); }
  void leave()       { LeaveCriticalSection(&cs_);  };
 
private:
  CRITICAL_SECTION cs_;
};
 
 
class CSLocker
{
public:
  CSLocker(CriticalSection* lock):lock_(lock)  { lock_->enter(); };
  ~CSLocker() { lock_->leave();}
private:
  CriticalSection* lock_;
};
 
template<typename T>
class Data
{
  T value()const
  {  
     CSLocker locker(&lock_);
     return value_;
  }
  
  void setValue(T value)
  {
    CSLocker locker(&lock_);
    value_= value;   
  } 
  
  private:
    mutable CriticalSection lock_;
    T value_;
};
Добавлено через 5 минут
или
C++
1
2
3
4
5
6
7
8
9
сlass Data
{
   public:
      long value()const { return value_; }
      void increment(){  InterlockedIncrement(&value_);  }
     
   private:
      volatile long value_; /*  но тут есть сомнения в необходимости volatile */
};
0
2 / 2 / 0
Регистрация: 23.01.2013
Сообщений: 23
08.03.2015, 16:52  [ТС]
Большое спасибо!
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.03.2015, 21:43
Цитата Сообщение от Avazart Посмотреть сообщение
Походу я зря ссылки кидал.
Прочитал я статью, ничего нового про volatile не узнал. Изменение volatile переменной происходит неатомарно. Неатомарный доступ к этой переменной из двух потоков никак не повлияет на актуальность переменной в данном случае, как у ТС, т.к.
Цитата Сообщение от kzru_hunter Посмотреть сообщение
один поток только записывает в переменную, а другой только считывает.
Эти велосипеды с interlocked и крит. секциями нужны в более сложных случаях, а это стандартная ситуация.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.03.2015, 21:50
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Изменение volatile переменной происходит неатомарно.
Неатамарный доступ, все приехали ... если доступ не атамарный это уже ошибка.
Interlocked это стандартное решение для счетчиков, критические секции для более сложных структур.
А полагаться на волю случая при доступе без синхронизации вот это безрассудно.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
08.03.2015, 21:53
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Неатомарный доступ к этой переменной из двух потоков никак не повлияет на актуальность переменной
Ну прямо. Вот один поток начал писать новое значение, да не закончил, а второй в это время начал читать. И чего в результате?
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.03.2015, 21:56
Цитата Сообщение от Avazart Посмотреть сообщение
Неатамарный доступ, все приехали ... если доступ не атамарный это уже ошибка.
Получается в примере в msdn тоже ошибка: https://msdn.microsoft.com/ru-... ttww7.aspx ?

Добавлено через 1 минуту
Цитата Сообщение от volvo Посмотреть сообщение
Ну прямо. Вот один поток начал писать новое значение, да не закончил, а второй в это время начал читать. И чего в результате?
это как в long можно начать писать значение, да не закончить?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.03.2015, 21:57
kzru_hunter, Лол там C# еще раз лучше прочитай Рихтера.
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.03.2015, 21:57
Цитата Сообщение от volvo Посмотреть сообщение
Ну прямо. Вот один поток начал писать новое значение, да не закончил, а второй в это время начал читать. И чего в результате?
это как в long можно начать писать, да не закончить?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.03.2015, 22:05
Таким образом, при работе с памятью, совместно используемой потоками, для всех архитектур, кроме ARM, настоятельно рекомендуется указывать параметр /volatile:iso и использовать явные примитивы синхронизации и встроенные функции компилятора.
Блок, относящийся к стандарту ISO

Если вы знакомы с ключевым словом C# volatile или разбираетесь в поведении volatile в более ранних версиях Visual C++, вам необходимо учитывать, что в стандарте ISO для языка C++11 ключевое слово volatile отличается. В Visual Studio такое ключевое слово поддерживается, если установлен параметр компилятора /volatile:iso. (Для архитектуры ARM он установлен по умолчанию). Ключевое слово volatile в коде, создаваемом согласно стандарту ISO для языка C ++11, должно использоваться только для аппаратного доступа; его использование для взаимодействия между потоками не допускается. Для взаимодействия между потоками необходимо использовать такие механизмы, как std::atomic<T> из стандартной библиотеки шаблонов C++.
https://msdn.microsoft.com/ru-... 04hfd.aspx

Добавлено через 4 минуты
Цитата Сообщение от kzru_hunter Посмотреть сообщение
это как в long можно начать писать, да не закончить?
Писать по 2 байта?
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
08.03.2015, 22:08
Avazart в volatile переменную значение записывается одной инструкцией
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.03.2015, 22:09
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Avazart в volatile переменную значение записывается одной инструкцией
Где это сказано?
Если запись была бы одной инструкцией, то это уже было атомарной операцией.
Но атомарность определяет не столько volatile, сколько сам тип объекта (размер объекта) и специфика выполнения операций на данной платформе.

volatile лишь не дает компилятору "оптимизировать переменную".
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.03.2015, 22:09
Помогаю со студенческими работами здесь

В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу
Добрый день. При запуске программы выскакивает вот такая вот ошибка. В чем может быть проблема и как ее исправить?

Ошибка соединения с БД "архитектура драйвера и приложения не соответствуют"
Работаю в RAD studio и столкнулся с проблемой, когда нужно установить связь приложения и БД. Установил драйвер ODBC все сделал - связь моей...

Архитектура многопоточного приложения
Всем привет. Есть объект, выполняющий ГУИ билдинг. Для этого необходимо загрузить данные из файла и далее записать(для...

Архитектура многопоточного приложения
Всем доброго времени суток. На даннй момент есть следующая задача: реализовать winForm приложение на основе потоков: в первом потоке...

Создание многопоточного приложения на VB.
Плз, подскажите, как сделать такую штуку: пока пользователь заполняет поля формы, данные в фоновом потоке подкачиваются в ComboBox


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru