LINUX.ORG.RU

static метод из разных потоков - есть ли подводные камни?

 ,


1

4

Давно хочу, но стесняюсь, спросить - ибо до конца не уверен в своих знаниях.

Вопрос в том, что могут ли быть проблемы при использовании статического метода (например класса) в программе, у которой несколько потоков могут вызывать этот метод «одновременно»?

Конечно речь только о таких методах, где на входе какие данные, потом эти данные как-то кодируем/декодируем и возвращаем результат. То есть в самом классе или в общих для всех потоков данных - ничего не меняем.

Я пользуюсь такими методами в своей проге на qt, c++, windows и пока проблем не замечено, но все же душа не спокойна…

Предполагаю, что при переключении с потока на другой поток ОС сохраняет контекст прерванного потока на стеке прерванного потока, а новый поток использует свой контекст (стек) и получается вроде бы проблем не должно быть…

Меня смущает, что все это слишком удобно (в программировании), чтобы не было проблем. Удобно - имеется в виду, что память под статику определяется один раз, то есть не надо создавать/уничтожать ничего.

В общем давно сомневаюсь в перспективах данного подхода, но продолжаю пользоваться.

Программа, которую верстаю и некоторые клиенты уже пользуются, конечно периодически падает, но в основном при отсутствии нужных dll оборудования. Отслеживаю это запуском предварительного отдельного стартера, который получает логи от основного приложения. Это я к тому, что процесс идёт под кое-каким контролем. В конце стартер выгружает на сервер в инете логи.



Последнее исправление: kkmspb (всего исправлений: 1)

Пока нет доступа на запись в одну и туже область памяти - проблем особо быть не должно. Если метод не оперирует связными с классом, к которому метод принадлежит, данными, а просто преобразует вход - в выход - все будет хорошо. Но тогда мы используем класс просто как namespace, смысл инкапсуляции пропадает.

Silerus ★★★★
()
Ответ на: комментарий от kkmspb

если они кем то другим,в чей то другой библиотеке, а так не вижу смысла, использовать классы как наймспайсы

Silerus ★★★★
()
Ответ на: комментарий от Silerus

Не суть можно и как namespace организовать , вопрос не в этом.

Мне иногда эти статические методы удобнее реализовывать в базовом классе для однотипного оборудования.

Кстати они становятся экспортируемыми когда надо или импортируемыми в зависимости от ключевого слова dll export (вроде так) в об’явлении класса.

kkmspb
() автор топика
Последнее исправление: kkmspb (всего исправлений: 1)

static метод, это обычная функция, просто спрятанная внутрь описания класса. и видящая внутренние обьекты класса, даже непубличные.

проблемы многопотока у нее - как у обычной функции.

alysnix ★★★
()
Ответ на: комментарий от alysnix

static метод, это обычная функция, просто спрятанная внутрь описания класса. и видящая внутренние обьекты класса, даже непубличные

Видеть внутренние об’екты класса из статик метода можно только если они тоже статик. Указатель на this то у вас где? Ни капли это не обычная функция.

kkmspb
() автор топика
Последнее исправление: kkmspb (всего исправлений: 1)
Ответ на: комментарий от kkmspb

Видеть внутренние об’екты класса из статик метода можно только если они тоже статик

да ты що! внутри класса могут быть локальные типы, классы, темплейты, перечисления, конструкторы/деструктор, операторы. и он их видит, даже если они приватные.

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

он даже может создать обькт данного класса приватным конструктором и вызвать его метод. а потом уничтожить приватным деструктором.

короче это обычная функция с необычной областью видимости.

alysnix ★★★
()
Ответ на: комментарий от kkmspb

Ни капли это не обычная функция.

Возможно вы её путаете с реентерабельной функцией. Именно реентерабельность позволяет её безопасно использовать в многопоточности. Классификатор доступа и связывания, в вашем случае static, не имеет отношения к этому свойству функции.

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

raspopov
()
Ответ на: комментарий от raspopov

Надо пояснить, что я хотел.

Имелось ввиду, что у Статик метода есть важный плюс - он присутствует в памяти в одном экземпляре (создаётся на этапе инициализации). Доступ к статик методу удобный из кода, везде через два двоеточия class1::static_method123, что может быть проще?

И вопрос в том - не будет ли проблемы при использовании этого метода из разных потоков. Только в этом вопрос.

Но как я понял из первого комментария, проблем не будет точно, если только изменять входные данные и их возвращать как результат.

Чему лично я ну очень рад. И кстати это все про С++98.

kkmspb
() автор топика
Последнее исправление: kkmspb (всего исправлений: 1)
Ответ на: комментарий от Silerus

а так не вижу смысла, использовать классы как наймспайсы

неймспейс в шаблон не закинешь

Stil ★★★★★
()
Ответ на: комментарий от kkmspb

у Статик метода есть важный плюс - он присутствует в памяти в одном экземпляре (создаётся на этапе инициализации)

Все функции существуют лишь в одном экземпляре. Статик функция это по сути обычная глобальная. Глобальная, которую сделали friend’ом вести себя будет аналогично, разве что отличия в ADL.

В общем, все функции одинаковы, нет никаких «особенных нетакусь», различия лишь в сахаре.

kvpfs_2
()
Ответ на: комментарий от kkmspb

Имелось ввиду, что у Статик метода есть важный плюс - он присутствует в памяти в одном экземпляре

Вот мне всегда страшно, когда такие «программисты» появляются на горизонте. Нет бы с первого ответа понять, что они ступили, и быстро побежать учить Страуструпа, а они напротив - продолжают тут публично закапываться в дно всё глубже и глубже…

raspopov
()
Ответ на: комментарий от kvpfs_2

Все функции существуют лишь в одном экземпляре. Статик функция это по сути обычная глобальная.

Вы наверное не обратили внимание, что у меня говорится о методе (класса). Во вторых если метод не Статик он создаётся каждый раз в памяти заново с созданием нового экземпляра класса, а Статик метод создаётся в памяти один раз ещё на этапе инициализации. Разве не так? Проверяется это очень просто.

В третьих вопрос изначально был вообще не об этом.

kkmspb
() автор топика
Последнее исправление: kkmspb (всего исправлений: 1)
Ответ на: комментарий от kkmspb

Во вторых если метод не Статик он создаётся каждый раз в памяти заново с созданием нового экземпляра класса

метод вообще не создается. это просто функция что в памяти лежит.

создается только сам обьект, то есть структура с полями, но не методами.

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от kkmspb

RTFM пожалуйста сделайте. У вас базы не хватает - Шилдта для начинающих какого перечитайте где всё разжевано. Пока видится в голове у вас каша и лазить в мультипоток для вас еще рановато.

necromant ★★
()

Нет, проблем не будет.

Проблемы могут быть, если static методы обращаются к static полям класса, причём на запись, а не только на чтение. Тогда будет нужна какая-нибудь синхронизация.

Если обращений к внешним данным кроме аргументов нет или оно только на чтение, то проблем нет.

KivApple ★★★★★
()
Ответ на: комментарий от kkmspb

Без обид, но согласен с постами выше - вам надо срочно читать букварь, у вас нет базы.

kvpfs_2
()

Вопрос в том, что могут ли быть проблемы при использовании статического метода (например класса) в программе, у которой несколько потоков могут вызывать этот метод «одновременно»?

Если «поток» это тред ядра то могут, если это кооперативная многозадачность то не могут

ahdenchik
()
Ответ на: комментарий от KivApple

Проблемы могут быть, если static методы обращаются к static полям класса, причём на запись, а не только на чтение. Тогда будет нужна какая-нибудь синхронизация.

Спасибо, за ответ, я как раз об этом и спрашивал.

kkmspb
() автор топика
Ответ на: комментарий от Silerus

Пока нет доступа на запись в одну и туже область памяти - проблем особо быть не должно. Если метод не оперирует связными с классом, к которому метод принадлежит, данными, а просто преобразует вход - в выход - все будет хорошо.

Спасибо за ответ, очень помогли.

kkmspb
() автор топика
Ответ на: комментарий от Silerus

Я тут вспомнил, почему я класс использую, а не namespace.

У меня этот статик метод (класса) должен при сборке в виде библиотеки dll торчать наружу, то есть быть экспортируемым.

А при использовании namespace и static функции происходит internal linkage, то есть не торчит наружу ничего в библиотеке, более того она и не линкуется с вызовами из других файлов.

Как-то так. С++98.

kkmspb
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.