Как я знаю, ориентирован ли этот метод C# на многопотоковое исполнение?

Используя эту функцию PHP mysql_escape_string(), вы можете быстро получить хорошую профилактику.

Например:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."'

mysql_escape_string - Сбрасывает строку для использования в mysql_query

Для большей профилактики вы можете добавить в конце ...

wHERE 1=1   or  LIMIT 1

Наконец вы получаете:

SELECT * FROM users WHERE name = '".mysql_escape_string($name_from_html_form)."' LIMIT 1
49
задан MatthewMartin 22 October 2014 в 03:38
поделиться

11 ответов

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

static void MyFunction(int x) { ... } // thread safe. The int is copied onto the local stack.

static void MyFunction(Object o) { ... } // Not thread safe. Since o is a reference type, it might be shared among multiple threads. 
52
ответ дан Cybis 7 November 2019 в 11:26
поделиться

Нет, addOne ориентирован на многопотоковое исполнение здесь - он только использует локальные переменные. Вот пример, который не был бы быть ориентированным на многопотоковое исполнение:

 class BadCounter
 {
       private static int counter;

       public static int Increment()
       {
             int temp = counter;
             temp++;
             counter = temp;
             return counter;
       }
 }

Здесь, два потока могли и назвать Инкремент одновременно и закончить тем только, что увеличили однажды. (Используя return ++counter; было бы так же плохо, между прочим - вышеупомянутое является более явной версией того же самого. Я развернул его так, это будет, более очевидно, неправильно.)

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

38
ответ дан Jon Skeet 7 November 2019 в 11:26
поделиться

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

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

можно получить блокировку на экземпляре любого ссылочного типа (например, наследовался Объекту, не оценивают типы как интервал или перечисления, и не пустые), но очень важно понять, что блокировка на объекте не имеет никакого свойственного эффекта на доступы к тому объекту, это только взаимодействует с другими попытками получить блокировку на том же объекте. Это до класса для защиты доступа к его членским переменным с помощью соответствующей схемы блокировки. Иногда экземпляры могли бы защитить многопоточные доступы к своим собственным участникам путем соединения себя (например, lock (this) { ... }), но обычно это не необходимо, потому что экземпляры имеют тенденцию быть сохраненными только одним владельцем и не должны гарантировать ориентированный на многопотоковое исполнение доступ к экземпляру.

чаще всего, класс создает частную блокировку (например, private readonly object m_Lock = new Object(); для отдельных блокировок в каждом экземпляре для защиты доступа к членам того экземпляра, или private static readonly object s_Lock = new Object(); для центральной блокировки для защиты доступа к статическим участникам класса). У Josh есть более определенный пример кода использования блокировки. Тогда необходимо кодировать класс для использования блокировки соответственно. В более сложных случаях Вы могли бы даже хотеть создать отдельные блокировки для различных групп участников, уменьшить конкуренцию для различных видов ресурсов, которые не используются вместе.

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

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

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

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

При контакте с классами платформы.NET, документами Microsoft в MSDN, ориентирован ли данный вызов API на многопотоковое исполнение (например, статические методы обеспеченных типов универсального набора как List<T> сделаны ориентированными на многопотоковое исполнение, в то время как методы экземпляра не могут быть - но проверить конкретно, чтобы быть уверенными). Подавляющее большинство времени (и если это конкретно не говорит, что это ориентировано на многопотоковое исполнение), это не внутренне ориентировано на многопотоковое исполнение, таким образом, это - Ваша обязанность использовать его безопасным способом. И даже когда отдельные операции реализованы внутренне ориентированные на многопотоковое исполнение, все еще необходимо волноваться об общем и перекрывающемся доступе кодом, если это делает что-либо более сложное, которое должно быть атомарным.

Один большой протест выполняет итерации по набору (например, с foreach). Даже если каждый доступ к набору получает устойчивое состояние нет никакой свойственной гарантии, что это не изменится промежуточный те доступы (если вообще где-нибудь еще может добраться до него). Когда набор сохранен локально обычно нет никакой проблемы, но набора, который мог быть изменен (другим потоком или во время выполнения Вашего цикла!) мог привести к непоследовательным результатам. Один простой способ решить это состоит в том, чтобы использовать атомарную ориентированную на многопотоковое исполнение операцию (в Вашей защитной схеме блокировки), чтобы сделать временную копию набора (MyType[] mySnapshot = myCollection.ToArray();) и затем выполнить итерации по той локальной копии моментального снимка вне блокировки. Во многих случаях это избегает потребности в содержании блокировки все время, но в зависимости от того, что Вы делаете в рамках повторения, которым это не может быть достаточно и просто необходимо защитить от изменений все время (или у Вас может уже быть он в заблокированном разделе, принимающем меры против доступа для изменения набора наряду с другими вещами, таким образом, это покрыто).

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

22
ответ дан Rob Parker 7 November 2019 в 11:26
поделиться

Ваш метод прекрасен, так как он только использует локальные переменные, давайте изменим Ваш метод немного:

static int foo;

static int addOne(int someNumber)
{
  foo=someNumber; 
  return foo++;
}

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

static int foo;
static object addOneLocker=new object();
static int addOne(int someNumber)
{
  int myCalc;
  lock(addOneLocker)
  {
     foo=someNumber; 
     myCalc= foo++;
  }
  return myCalc;
}

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

7
ответ дан JoshBerke 7 November 2019 в 11:26
поделиться

Существует некоторое продолжение исследования, которое позволяет Вам обнаруживать неориентированный на многопотоковое исполнение код. Например, проект ШАХМАТЫ в Microsoft Research .

3
ответ дан Thomas Danecker 7 November 2019 в 11:26
поделиться

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

Это в основном, что Вы высматриваете. Ориентированный на многопотоковое исполнение означает что функция также:

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

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

А тривиальный пример неориентированной на многопотоковое исполнение версии Вашей функции был бы этим:

private int myVar = 0;

private void addOne(int someNumber)
{
   myVar += someNumber;
}

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

3
ответ дан TheSmurf 7 November 2019 в 11:26
поделиться

В вышеупомянутом примере нет.

Потокобезопасность должна главным образом сделать с сохраненным состоянием. Можно сделать вышеупомянутый пример не ориентированным на многопотоковое исполнение путем выполнения этого:

static int myInt;

static int addOne(int someNumber){
myInt = someNumber;
return myInt +1; 
}

Это будет означать, что из-за контекстного переключения распараллеливают 1, мог бы добраться до вызова myInt = someNumber и затем контекстное переключение, позволяет, говорят, что поток 1 просто установил его на 5. Тогда предположите, что распараллеливают 2, входит и использует 6 и возвращается 7. Тогда, когда поток 1 просыпается снова, он будет иметь 6 в myInt вместо 5, что он использовал, и возвратитесь 7 вместо ожидаемых 6.: O

2
ответ дан Quibblesome 7 November 2019 в 11:26
поделиться

Где угодно, ориентированный на многопотоковое исполнение средства, что у Вас нет двух или больше столкновений потоков при доступе к ресурсу. Обычно статический varaiables---на языках как C#, VB.NET и Java---сделал Ваш код , распараллеливают небезопасный .

В Java существует , синхронизировался ключевое слово. Но в.NET Вы получаете опцию/директиву блока:


class Foo
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    public void Bar(object obj)
    {
        // do something...
    }
}

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

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

1
ответ дан daniel 7 November 2019 в 11:26
поделиться

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

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

0
ответ дан Oskar 7 November 2019 в 11:26
поделиться

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

0
ответ дан yfeldblum 7 November 2019 в 11:26
поделиться

Причина, что 'нечто' и 'someNumber' безопасны в Вашем примере, состоит в том, что они находятся на стеке, и каждый поток имеет их собственный стек и не совместно использован - также.

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

0
ответ дан quamrana 7 November 2019 в 11:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: