Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
2 / 2 / 0
Регистрация: 03.06.2009
Сообщений: 102

реализация ThreadSafe функции

24.07.2013, 14:23. Показов 2992. Ответов 37
Метки нет (Все метки)

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

На первое время решил добавить в функции вот такую конструкцию:
C++
1
2
3
4
5
6
7
8
int some_function{
  static UINT32 entryCounter = 0;
  while(entryCounter!= 0) Sleep(1);{
    entryCounter++;
    //тело функции
     entryCounter--;
  }
}
проблемы ушли, но интересно насколько корректный вариант получился и есть ли другие варианты решения данной проблемы?
Спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.07.2013, 14:23
Ответы с готовыми решениями:

Являются ли new / malloc threadsafe?
И, если не являются, как организовать выделение памяти для многопоточной системы? Ставить мьютекс как-то слишком, особенно если выделяется...

Реализация функции печати результатов предыдущей функции
Была написана программа с функцией, находящая результат выражения с аргументом, значения которого заданы параметром со значениями и шагом....

Реализация функции c++
Программа: #include <iostream> using namespace std; struct Node { int data; Node* next; };

37
2 / 2 / 0
Регистрация: 03.06.2009
Сообщений: 102
25.07.2013, 13:52  [ТС]
Студворк — интернет-сервис помощи студентам
Вроде бы понял.
Спасибо большое за книжку, почитаю.

Добавлено через 20 часов 34 минуты
подумав, понял что инициализацию и удаление надо из функций выносить и решил сделать так:
1. Переменные критических секций поля класса.
2. Инициализация при открытии устройства.
3. Использование в функциях.
4. удаление в функции закрытии устройства.
В коде получается так:
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
class my_class{
public:
    CRITICAL_SECTION g_cs;
 
    void open();
    void function();
    void close();
};
 
void my_class::open(){
  //Открытие устройства
  InitializeCriticalSection(&g_cs);
}
 
void my_class::function(){
  EnterCriticalSection(&g_cs);
  int a = 5;
  LeaveCriticalSection(&g_cs);
}
 
void my_class::close(){
  DeleteCriticalSection(&g_cs);
  //Закрытие устройства
}
есть ли слабые места у этого способа?
Спасибо.
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 13:54
Я всегда так делаю
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
25.07.2013, 14:02
Цитата Сообщение от smithana Посмотреть сообщение
есть ли слабые места у этого способа?
Есть. Забудете однажды вызвать close и все повиснет.
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 14:21
Чота я невнимателен был, я не так делаю. Уменя обычно в конструкторах EnterCriticalSection(...), а в деструкторах DeleteCriticalSection(...).

Добавлено через 15 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
Есть. Забудете однажды вызвать close и все повиснет.
Не аргумент - забыть можно всё что угодно, и даже если не повиснет, это будет баг, который надо будет искать в любом случае. Тем более что баг, который приводит к зависанию проще отловить.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
25.07.2013, 14:25
Цитата Сообщение от Praktolock Посмотреть сообщение
Тем более что баг, который приводит к зависанию проще отловить.
Ооо! А если оно "зависает" раз в месяц, только на оборудовании Заказчика, и еще нерегулярно - в зависимости от положения звезд?

Собссна, я уверен, что пару раз поискав такие трудноуловимые баги в ночь перед релизом, ТС быстро придет к мысли об использовании RAII.....
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 14:35
Цитата Сообщение от CheshireCat Посмотреть сообщение
если оно "зависает" раз в месяц, только на оборудовании Заказчика, и еще нерегулярно
Ок, тогда будет найти сложнее)
Всё-таки я считаю, что просто нужно взять привычку - не забывать. А то можно подумать, что забыть что-нибудь другое вполне приемлемо.

Добавлено через 4 минуты
Цитата Сообщение от CheshireCat Посмотреть сообщение
ТС быстро придет к мысли об использовании RAII.....
Кстати, приведи пример, как бы ты в данном случае использовал бы RAII? Не пытаюсь мериться, действительно интересно.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
25.07.2013, 15:01
Ну в данном то случае оно тривиально:
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
#include <windows.h>
 
class locker
{
    CRITICAL_SECTION* cs;
 
public:
    locker(CRITICAL_SECTION* obj): cs(obj)
    {
        ::EnterCriticalSection(cs);
    };
    ~locker()
    {
        ::LeaveCriticalSection(cs);
    }
};
 
class my_class
{
    CRITICAL_SECTION g_cs;
 
public:
    my_class()
    {
        ::InitializeCriticalSection(&g_cs);
    }
    ~my_class()
    {
        ::DeleteCriticalSection(&g_cs);
    }
    void some_function();
};
 
void my_class::some_function()
{
    locker(&g_cs);
    int a = 5;
}
 
int main()
{
    // ......
}
1
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 15:16
Цитата Сообщение от CheshireCat Посмотреть сообщение
locker(&g_cs);
У тебя после конструктора сразу деструктор вызовется. МБ нужно всё таки экземпляр где-то сохранить?
А за идею спасибо
0
2 / 2 / 0
Регистрация: 03.06.2009
Сообщений: 102
25.07.2013, 15:17  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Есть. Забудете однажды вызвать close и все повиснет.
ну это будет проблема разработчика приложения. Я думаю ему всё-таки будет легче не забывать close вызывать, чем самому с threadSafe разбираться.

Цитата Сообщение от Praktolock Посмотреть сообщение
Чота я невнимателен был, я не так делаю. Уменя обычно в конструкторах EnterCriticalSection(...), а в деструкторах DeleteCriticalSection(...).
а где же InitializeCriticalSection?
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 15:20
Цитата Сообщение от smithana Посмотреть сообщение
а где же InitializeCriticalSection?
Опечатка: в конструкторе InitializeCriticalSection
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
25.07.2013, 15:22
Цитата Сообщение от Praktolock Посмотреть сообщение
У тебя после конструктора сразу деструктор вызовется.
Не сразу, а при выходе из метода.
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 15:24
Цитата Сообщение от castaway Посмотреть сообщение
Не сразу, а при выходе метода.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
{
public:
 int value;
 A(){printf("A::A()\n");};
~A(){printf("A::~A()\n");};
};
 
int main()
{
 A();
 printf("s tvoih slov destructor doljen bit vizvan posle etoy stroki\n");
 _getch();
 return 0;
}
вывод:
A::A()
A::~A()
s tvoih slov destructor doljen bit vizvan posle etoy stroki
0
2 / 2 / 0
Регистрация: 03.06.2009
Сообщений: 102
25.07.2013, 15:26  [ТС]
Цитата Сообщение от Praktolock Посмотреть сообщение
Опечатка: в конструкторе InitializeCriticalSection
на первое время так и сделаю.

в RAII чуть позже постараюсь вникнуть. По первым впечатлениям вещь очень нужная.

Спасибо!
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 15:29
Цитата Сообщение от Убежденный Посмотреть сообщение
Забудете однажды вызвать close и все повиснет.
Цитата Сообщение от CheshireCat Посмотреть сообщение
locker(&g_cs);
Забыли один раз экземпляру имя дать и получился баг

Добавлено через 1 минуту
который
Цитата Сообщение от CheshireCat Посмотреть сообщение
"зависает" раз в месяц, только на оборудовании Заказчика, и еще нерегулярно - в зависимости от положения звезд
Добавлено через 35 секунд
Так может быть, всё таки не в идеологии дело, а втом что нужно учиться не забывать?
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
25.07.2013, 15:33
Praktolock,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdio>
 
class A
{
public:
    int value;
    A() { printf("A::A()\n"); }
    ~A() { printf("A::~A()\n"); }
};
 
int main()
{
    A   a;
    printf("s tvoih slov destructor doljen bit vizvan posle etoy stroki\n");
    return 0;
}
Вывод:
A::A()
s tvoih slov destructor doljen bit vizvan posle etoy stroki
A::~A()
Просто надо уметь правильно это использовать.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
25.07.2013, 15:33
Верно, забыл. Писал код прямо в редакторе форума. Виноват-с... :-(
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
25.07.2013, 15:33
Цитата Сообщение от Praktolock Посмотреть сообщение
Не аргумент - забыть можно всё что угодно, и даже если не повиснет, это будет баг, который надо будет искать в любом случае. Тем более что баг, который приводит к зависанию проще отловить.
Цитата Сообщение от smithana Посмотреть сообщение
ну это будет проблема разработчика приложения. Я думаю ему всё-таки будет легче не забывать close вызывать, чем самому с threadSafe разбираться.
Ошибаетесь, господа.
Как только в коде появляются ветвления, такие ошибки начинают возникать на пустом месте.
И во время внесения изменений (рефакторинг) с таким подходом будет очень легко напортачить,
если использовать "голые" программные интерфейсы, не прикрытые RAII.
Интерфейсы open-do-close хороши только в вырожденных случаях, сведенных к функциям в
двадцать строк, где все на ладони и нет инвариантов.

Кроме того, если во время использования "голого" интерфейса кто-нибудь кинет исключение,
очистка ресурсов не будет выполнена и произойдет утечка. Так что без RAII никуда.

Цитата Сообщение от Praktolock Посмотреть сообщение
Так может быть, всё таки не в идеологии дело, а втом что нужно учиться не забывать?
Можно держать в уме все нужные контакты и планы встреч.
А можно пользоваться ежедневником и напоминалками, освобождая мозг для других задач.
Я предпочитаю второе.
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
25.07.2013, 15:41
Цитата Сообщение от Убежденный Посмотреть сообщение
если во время использования "голого" интерфейса кто-нибудь кинет исключение,
очистка ресурсов не будет выполнена и произойдет утечка
Если "кто-то" кинет исключение не предусмотренное мной, это краш программы, и ресурсы ей больше не понадобятся.
Впрочем я не пытаюсь сказать, что RAII это плохо. И в принципе на 95% согласен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.07.2013, 15:41

Реализация функции принтф
Хелпуем товарищи, треба написать свою фукнцию принтф с форматной строкой(правда она слегка иная, чтобы не путать с уже существующей) ...

Реализация функции srcat.
Я написал (реализовал) функцию strcat. Вот ... #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace...

Реализация функции erase()
Как работает erase()? То есть, если у нас : prev, it, next - итераторы и выполняя erase(it), она очистит память, которую занимала it и...

Реализация функции strtok
Добрый день. Мое задание звучит так: изучите поведение функции strtok из стандартной библиотеки. Реализуйте и...

Реализация friend функции
Есть код. Нужно реализовать вывод ответа через friend. Подскажите пожалуйста как это сделать? Ничего не получается... #include...


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

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
После бана на Пикабу не работает авторизация аккаунта с Яндекса.
Hrethgir 09.07.2026
В частности https:/ / auto. ru/ logbook/ zapret-na-vozhdenie-posle-65-let_1cf28789-07b4-4c75-a2f7-4cd4edf9deeb тут хотел оставить комментарий такой Зрите в корень - монополизация на разработку программ. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru