Являются ли глобальные переменные плохими?

195

В C/С++ глобальные переменные так же плохи, как считает мой профессор?

  • 17
    Я укушу на случай, если он попытается рассказать шутку ... "Насколько они плохи"?
  • 0
    stackoverflow.com/questions/357187/...
Показать ещё 8 комментариев
Теги:
global-variables

28 ответов

228

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

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

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

  • 9
    Этот ответ действительно хорош. Объедините это с ответом «минимизируйте переменную область» stackoverflow.com/questions/357187/…
  • 13
    Замените «class» на «application» и «object state» на «global state», и вы получите точно такой же аргумент, чтобы не использовать переменные-члены (иначе поля) в классах. Реальный ответ - используйте их, когда это уместно.
Показать ещё 7 комментариев
67

Важно помнить общую цель: ясность

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

Однако, как и многие правила, люди помнят правило, а не то, что предназначалось правилу.

Я видел программы, которые, похоже, удваивают размер кода, передавая огромное количество параметров только для того, чтобы избежать зла глобальных переменных. В конце концов, использование глобалов сделало бы программу более ясной для тех, кто ее читает. Бездумно придерживаясь слова правила, первоначальный программист не смог реализовать правило.

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

  • 6
    Предложение использовать глобальные вместо передачи переменных является рецептом, чтобы сделать ваш код не пригодным для повторного использования и небезопасным для многопоточности
  • 11
    Предлагая глобальные переменные в правильных обстоятельствах, это рецепт более ясного и высокопроизводительного кода. «Передача» требует постоянного динамического выделения памяти, и это было бы глупо для чего-то, что должно быть глобальным, например глобального буфера для входящих данных сокета. Например, если у вас есть функция, которая читает Winsock recv (), зачем постоянно создавать и освобождать этот буфер в каждом вызове? Сделайте буфер глобальным. Несколько потоков не будут читать это в любом случае.
Показать ещё 4 комментария
54

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

  • 21
    Это точно. Они как gotos, если вы не знаете, когда их использовать, то никогда не делайте.
  • 5
    В моей нынешней компании они static используют static глобальные переменные, язык - C. Будучи ограниченным относительно небольшими единицами перевода, они начинают напоминать переменные класса объектов C ++.
Показать ещё 3 комментария
32

Глобальные переменные должны использоваться только тогда, когда у вас нет альтернативы. И да, это включает в себя Singletons. 90% времени, глобальные переменные вводятся для экономии затрат на прохождение вокруг параметра. И затем происходит многопоточное/модульное тестирование/обслуживание, и у вас есть проблема.

Итак, да, в 90% ситуаций глобальные переменные плохи. Исключения, вероятно, не будут замечены вами в ваши годы колледжа. Единственное исключение, которое я могу придумать с головы, имеет дело с глобально глобальными объектами, такими как таблицы прерываний. Такие вещи, как соединение с БД, кажутся глобальными, но это не так.

  • 2
    Единственным исключением, которое я видел в студенческие годы, были функции графического обратного вызова. В XWindows у мышиных обратных вызовов не было аргументов void * data, которые позволяли бы вам передавать произвольные куски состояния программы ... (не то, что это в конечном итоге НАМНОГО лучше, чем глобальное в любом случае ...)
  • 10
    +1 за «Такие вещи, как соединение с БД, кажутся глобальными, но это не так».
Показать ещё 1 комментарий
23

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

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

Например, если у вас есть простая глобальная целочисленная переменная, которая используется в качестве перечислимого индикатора, который различные компоненты используют в качестве конечного автомата, и вы затем вносите изменения, добавляя новое состояние для нового компонента, вы должны затем проследить все остальные компоненты, чтобы гарантировать, что изменение не повлияет на них. Примером возможной проблемы может быть case когда оператор switch для проверки значения глобальной переменной перечисления с операторами case для каждого из текущих значений используется в разных местах, и бывает, что некоторые операторы switch не имеют случай по default для обработки неожиданного значения для глобального внезапно у вас есть неопределенное поведение в отношении приложения.

С другой стороны, использование общей области данных может использоваться для хранения набора глобальных параметров, на которые ссылаются в приложении. Этот подход часто используется со встроенными приложениями с небольшим объемом памяти.

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

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

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

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

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

Конфликт имен может быть проблемой с использованием глобальных переменных. Локальная переменная, имя которой совпадает с именем глобальной переменной, может скрывать глобальную переменную. Вы также сталкиваетесь с проблемой соглашения об именах при использовании языка программирования C. Обходной путь - разделить систему на подсистемы с глобальными переменными для конкретной подсистемы, начинающимися с тех же первых трех букв (см. Это при разрешении коллизий пространства имен в задаче C). C++ предоставляет пространства имен, а с C вы можете обойти это, создав глобально видимую структуру, членами которой являются различные элементы данных и указатели на данные и функции, которые предоставляются в файле как статические, следовательно, с видимостью файла только для того, чтобы они могли быть только ссылка через глобально видимую структуру.

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

Использование namespace C++ и struct Technique для C

Для языка программирования C++ директива namespace является огромной помощью в уменьшении шансов столкновения имен. namespace вместе с class и различными ключевыми словами доступа (private, protected и public) предоставляют большинство инструментов, необходимых для инкапсуляции переменных. Однако язык программирования C не предоставляет эту директиву. Эта публикация потока стека, Пространства имен в C, предоставляет некоторые методы для C.

Полезный метод состоит в том, чтобы иметь единственную резидентную область данных в памяти, которая определена как struct которая имеет глобальную видимость, и внутри этой struct есть указатели на различные глобальные переменные и функции, которые предоставляются. Фактические определения глобальных переменных задаются областью файла с использованием ключевого слова static. Если затем вы используете ключевое слово const чтобы указать, какие из них доступны только для чтения, компилятор может помочь вам обеспечить доступ только для чтения.

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

  • 0
    Это лучший пример объяснения, объясняющий все, что есть. Престижность!
  • 0
    Ваш язык должен иметь кодовое правило, которое не позволит вам использовать слишком много связывания классов.
18

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

Смотрите эту статью: Buggy breathalyzer code отражает важность обзора источника

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

Человек, я уверен, эти разработчики желают, чтобы они не использовали глобальные переменные!

  • 4
    Это был лучший смех за всю мою жизнь. Настоящий пример того, почему разработка с закрытым исходным кодом для получения прибыли - это плохо, а хороший пример глобальных изменений не работает!
18

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

Другими словами, это долгосрочная косвенная стоимость, и поэтому большинство людей думают, что это не так.

18

Я бы ответил на этот вопрос другим вопросом: используете ли вы singeltons/Непоняты ли синглтоны?

Потому что (почти все) использование singelton - это прославленная глобальная переменная.

  • 10
    Я собирался опубликовать умный комментарий, говорящий: «Они плохие, только если вы называете их глобальными, а не одиночными», но вы меня опередили.
  • 0
    Я все еще пытаюсь выяснить, что, черт возьми, синглетоны LOL.
Показать ещё 3 комментария
16

Глобальные переменные так же плохи, как вы их делаете, не менее.

Если вы создаете полностью инкапсулированную программу, вы можете использовать глобальные переменные. Это "грех" для использования глобалов, но программирование грехов является довольно философским.

Если вы посмотрите L.in.oleum, вы увидите язык, переменные которого являются исключительно глобальными. Это невозможно, потому что у библиотек нет выбора, кроме как использовать глобальные переменные.

Тем не менее, если у вас есть выбор, и вы можете игнорировать философию программистов, глобальные переменные не так уж плохи.

Также нет Gotos, если вы используете их правильно.

Большая "плохая" проблема заключается в том, что если вы используете их неправильно, люди кричат, высаживается марс, и мир взрывается.... или что-то в этом роде.

  • 15
    Недооценивать проблемы использования глобалов для запутанного студента не очень хорошая идея IMO.
  • 3
    Философия дизайна не объективна. Не в списке. То, что большинству программистов что-то не нравится, вовсе не означает, что никто не должен в это вглядываться. Легко сделать глобальное использование глобалов без конца мира. Пусть он делает это, борется (зная, что он будет), и учится как.
Показать ещё 3 комментария
11

Как сказал кто-то (я перефразирую) в другом потоке "Правила вроде этого не должны быть сломаны, пока вы не поймете все последствия этого".

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

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

  • 1
    Я согласен, если вы понимаете последствия, это нормально нарушать правила, но если вы ловите себя на том, что делаете это часто, вы делаете что-то не так
9

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

Несколько профи:

  • Доступ к любой функции.
  • Доступ к ним из нескольких потоков.
  • Никогда не выйдет из области действия до завершения программы.

Несколько минусов:

  • Доступ к любой из функций, без необходимости явно вставляться в качестве параметра и/или документироваться.
  • Небезопасный поток.
  • Загрязняет глобальное пространство имен и потенциально вызывает конфликты имен, если не приняты меры для предотвращения этого.

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

Несколько возможных решений некоторых проблем:

  • Подумайте, действительно ли это лучшее или наиболее эффективное решение проблемы. Если есть какие-то лучшие решения, используйте их вместо этого.
  • Поместите их в пространство имен [С++] или singleton struct [C, С++] с уникальным именем (хорошим примером может быть Globals или GlobalVars)) или использовать стандартизованное соглашение об именах для глобальных переменных (например, global_[name] или g_module_varNameStyle (как упоминается underscore_d в комментариях)). Это будет документировать их использование (вы можете найти код, который использует глобальные переменные, путем поиска имени пространства имен/структуры) и минимизировать влияние на глобальное пространство имен.
  • Для любой функции, которая обращается к глобальным переменным, явным образом документирую, какие переменные она читает и которую она пишет. Это облегчит поиск неисправностей.
  • Поместите их в свой исходный файл и объявите их extern в соответствующем заголовке, поэтому их использование может быть ограничено единицами компиляции, которым необходимо получить к ним доступ. Если ваш код опирается на множество глобальных переменных, но каждому модулю компиляции нужен только доступ к нескольким из них, вы можете рассмотреть их сортировку на несколько исходных файлов, поэтому проще ограничить доступ каждого файла к глобальным переменным.
  • Настройте механизм блокировки и разблокировки их и/или создайте свой код, чтобы как можно меньше функций нужно было изменять глобальные переменные. Чтение их намного безопаснее, чем их запись, хотя расписания потоков могут все еще создавать проблемы в многопоточных программах.
  • В принципе, свести к минимуму доступ к ним и максимизировать уникальность имени. Вы хотите избежать конфликтов имен и иметь как можно меньше функций, которые могут потенциально изменить любую данную переменную.

Являются ли они хорошими или плохими, зависит от того, как вы их используете. Большинство склонны использовать их плохо, следовательно, общая осторожность по отношению к ним. Если они используются правильно, они могут стать основным благом; если их использовать плохо, однако они могут и будут возвращаться, чтобы укусить вас, когда и как вы меньше всего этого ожидаете.

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


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

  • 0
    +1 за прагматизм. Синглтон часто просто добавляет шаблон, чтобы превратить экземпляр и рефакторинг в члены, и вы получите ... глобальные переменные, просто маскирующиеся под другим именем. Зачем беспокоиться, кроме как избежать греха глобалов из-за простоты техники? Пространства имен хороши как барьер, но я считаю простой g_module_varNameStyle разборчивым. Чтобы быть ясным, я не использую глобальные переменные, если я могу легко избежать этого - ключевое слово легко , потому что, поскольку я перестал верить, что их нужно избегать - или, скорее, запутать - любой ценой, я провожу намного лучше, код (шок!) намного аккуратнее
  • 0
    @underscore_d В основном это просто способ различать глобальные и локальные переменные, а также упростить поиск глобальных переменных при поиске в вашем коде, чтобы избежать путаницы в отношении того, является ли переменная глобальной или локальной / параметр / член / и т. д. Стандартное соглашение об именах, подобное вашему, работает так же хорошо, если оно согласовано. Редактирование моего ответа с использованием стандартной идеи соглашения об именах, спасибо.
Показать ещё 1 комментарий
9

Глобальные переменные, как правило, плохие, особенно если другие люди работают над одним и тем же кодом и не хотят тратить 20 минут на поиск всех мест, на которые ссылается переменная. И добавление потоков, которые изменяют переменные, приводит к совершенно новому уровню головных болей.

Глобальные константы в анонимном пространстве имен, используемом в одной единице перевода, являются прекрасными и повсеместными в профессиональных приложениях и библиотеках. Но если данные изменяемы и/или должны быть разделены между несколькими TU, вы можете их инкапсулировать - если не ради дизайна, то для кого-либо, отлаживающего или работающего с вашим кодом.

8

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

  • 0
    ленивая метафора лишена контекста! = ответ
  • 1
    @underscore_d: я не согласен. Это вопрос для обсуждения, даже если он не помечен как таковой (вероятно, из-за его возраста), и поэтому ответы, подобные этому, совершенно верны, и он подчеркивает, что действительно отвечает на вопрос ОП.
7

Абсолютно нет. Неправильное использование их, хотя... это плохо.

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

  • 3
    -1 Существует множество причин для предостережения относительно глобальных переменных: для меня самая большая из них заключается в том, что скрытые зависимости и глобальные возможности делают тестирование кода любым предсказуемым способом чрезвычайно трудным. Если вы не цените возможность автоматического тестирования кода, я бы сказал, что глобальные переменные не причинят вам ничего, кроме боли. И кроме того, в хорошо структурированной программе всегда есть альтернативы.
  • 1
    Вы говорите, что это чрезмерная генерализация, осторожное использование глобального состояния не мешает автоматическому тестированию - фактически почти все приложения имеют глобальное состояние, независимо от того, упаковано ли оно в динамически распределяемые экземпляры хорошо инкапсулированных объектов или статические данные, которые полностью его раскрывают концептуально не имеет значения, есть еще зависимости - речь идет о том, как они кодируются.
Показать ещё 1 комментарий
7

Я думаю, что ваш профессор пытается остановить плохую привычку, прежде чем она начнется.

Глобальные переменные имеют свое место, и, как многие люди говорят, знать, где и когда их использовать, может быть сложно. Поэтому я думаю, вместо того, чтобы вникать в сумасшедшие проблемы, почему, как, когда и где глобальные переменные ваш профессор решил просто запретить. Кто знает, он может запретить их в будущем.

7

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

4

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

Это означает, что вы можете легко привыкнуть к их использованию во время обучения. Это то, к чему пытается защитить ваш профессор.

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

3

Да, потому что, если вы позволите некомпетентным программистам использовать их (прочитайте 90%, особенно ученых), вы получите более 600 глобальных переменных, распространяемых более чем на 20+ файлов, и проект из 12 000 строк, где 80% функций недействительны, возвращают void, и полностью работают на глобальном уровне.

Быстро становится невозможно понять, что происходит в любой момент, если вы не знаете весь проект.

3

Нет, они совсем не плохие. Вам нужно посмотреть (машинный) код, созданный компилятором, чтобы сделать это определение, иногда гораздо хуже использовать локальный, чем глобальный. Также обратите внимание, что статическое действие на локальную переменную в основном делает ее глобальной (и создает другие уродливые проблемы, которые может решить реальный глобальный). "Локальные глобальные перемены" особенно плохи.

Глобалы дают вам чистый контроль над использованием вашей памяти, что гораздо труднее сделать с местными жителями. В наши дни это имеет значение только во встроенных средах, где память довольно ограничена. Что-то, что нужно знать, прежде чем вы предполагаете, что встроенные такие же, как в других средах, и предполагайте, что правила программирования одинаковы по всем направлениям.

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

Если вы будете следовать всем правилам программирования, преподаваемым вам в школе или книгам, ваша карьера программирования будет крайне ограничена. Вы можете выживать и иметь плодотворную карьеру, но ширина и ширина доступных вам сред будут крайне ограниченными. Если вы знаете, как и почему правило существует и может защитить его, это хорошо, если вы только рассуждаете, "потому что мой учитель так сказал", хорошо, что это не так хорошо.

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

В то же время, тогда просто сделайте то, что говорит самый громкий или несет самую большую палочку (до тех пор, пока вы не будете кричать громче и не будете иметь самую большую палку).

  • 4
    Это просто еще один способ сказать: «Никто никогда не был уволен за покупку IBM»?
  • 1
    Хорошая мысль, что для некоторых приложений использование глобальных переменных может на самом деле облегчить работу. В общем, использование глобальных переменных является источником проблем со скрытыми путями связи между разделами источника. Однако наличие области общей памяти, на которую ссылаются как на глобальную, используется для ряда реализаций, таких как интерфейсы устройства или, возможно, таблица глобальных параметров, содержащая различные виды констант или таблица переходов.
2

Я хотел бы возразить против того, что во всей этой теме делается то, что делает многопоточность труднее или невозможнее. Глобальные переменные являются общим состоянием, но альтернативы глобальным переменным (например, прохождение указателей) также могут делиться состоянием. Проблема многопоточности заключается в том, как правильно использовать общее состояние, а не то, является ли это состояние доступным через глобальную переменную или что-то еще.

В большинстве случаев, когда вы выполняете многопоточность, вам нужно что-то поделиться. Например, в шаблоне производителя-потребителя вы можете обмениваться потоковой безопасностью, содержащей рабочие единицы. И вам разрешено делиться им, потому что эта структура данных является потокобезопасной. Независимо от того, является ли эта очередь глобальной или нет, это совершенно не имеет значения, когда дело касается безопасности потоков.

Предполагаемая надежда, выраженная в этом потоке, заключается в том, что преобразование программы из однопоточного в многопоточное будет проще, если не использовать глобальные переменные наивно. Да, глобалы облегчают стрельбу в ногу, но есть много способов стрелять в себя.

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

2

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

Но ваш профессор прав, потому что он поднимает проблемы безопасности, поэтому следует избегать использования глобальных переменных. Глобальные переменные также создают проблемы, которые иногда трудно отлаживать.

Например: -

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

1

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

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

1

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

1

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

Использование глобального вместо передачи аргумента часто происходит быстрее, но если вы пишете многопоточное приложение, которое вы часто делаете в настоящее время, оно, как правило, не работает очень хорошо (вы можете использовать thread-statics, но затем увеличить производительность является сомнительным).

1

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

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

0

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

0

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

-1

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

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

Подробнее об этом здесь https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code

  • 0
    Для потомков: это отчасти правильно в лучшем случае. «Локальные переменные» в этом ответе относятся к локальным переменным потока , а не к более распространенным локальным переменным области видимости, на которые ссылается OP. Побочные эффекты изменения глобальных переменных небезопасным способом сильно отличаются от побочных эффектов, связанных с изменением глобального состояния не одновременно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню