powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как именно происходит блокировка (lock)?
25 сообщений из 38, страница 1 из 2
Как именно происходит блокировка (lock)?
    #38763890
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например, в одном потоке я делаю перечисление по объекту с типом IEnumerable, а в другом блокирую (lock) этот объект. Тогда итератор в первом потоке "замрёт" на последней итерации? Или что произойдёт?
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763897
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42Например, в одном потоке я делаю перечисление по объекту с типом IEnumerable, а в другом блокирую (lock) этот объект. Тогда итератор в первом потоке "замрёт" на последней итерации? Или что произойдёт?

Если ты не делаешь лок в перечислении, то ничего не произойдет
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763900
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42Тогда итератор в первом потоке "замрёт" на последней итерации?Нет
НемоКэп42Или что произойдёт?Простыми словами lock блокирует участок кода.
И если поток доходит до этого участка, а он в это время выполняется другим потоком, то первый подождёт последнего.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763910
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAНемоКэп42Или что произойдёт?Простыми словами lock блокирует участок кода.
И если поток доходит до этого участка, а он в это время выполняется другим потоком, то первый подождёт последнего.
Т. е. тот поток, который заблокировал объект IEnumerable, будет ждать тот поток, который его не блокировал? А в чём смысл тогда? Вроде, lock должен сделать тот поток, который этот lock применяет, "более главным" в смысле владения объектом, который lock блокирует. А так получается, что можно и без lock блокировать.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763916
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42skyANAпропущено...
Простыми словами lock блокирует участок кода.
И если поток доходит до этого участка, а он в это время выполняется другим потоком, то первый подождёт последнего.
Т. е. тот поток, который заблокировал объект IEnumerable, будет ждать тот поток, который его не блокировал?Нет.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763921
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42,
Щас придет свеном, и расскажет вам про критические дни с примерами кода, если сами не можете понять эту безделицу
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763927
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При помощи lock фрагмент кода помечается как критическая секция. То есть блокируется не объект, а кусок кода.

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

Вот второму придётся подождать, пока первый закончит записывать файл :)
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763980
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAПри помощи lock фрагмент кода помечается как критическая секция. То есть блокируется не объект, а кусок кода.

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

Вот второму придётся подождать, пока первый закончит записывать файл :)
А если второй начал писать в файл раньше, но без lock, а первый дошёл до этого места и хочет писать тоже, но уже с lock? Я вот эту ситуацию спрашивал.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38763986
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42А если второй начал писать в файл раньше, но без lock, а первый дошёл до этого места и хочет писать тоже, но уже с lock? Я вот эту ситуацию спрашивал.Разумеется, оба будут писать одновременно.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764016
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42А если второй начал писать в файл раньше, но без lock, а первый дошёл до этого места и хочет писать тоже, но уже с lock? Я вот эту ситуацию спрашивал.

Если один поток выполняет что-то внутри lock(someObject), то другой поток ни в одну другую секцию lock(someObject) зайти не сможет, пока первый ее не закончит
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764035
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При условии, что SomeObject - один и тот же объект (и не null)
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764063
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42skyANAПри помощи lock фрагмент кода помечается как критическая секция. То есть блокируется не объект, а кусок кода.

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

Вот второму придётся подождать, пока первый закончит записывать файл :)
А если второй начал писать в файл раньше, но без lock, а первый дошёл до этого места и хочет писать тоже, но уже с lock? Я вот эту ситуацию спрашивал.До этого места, но уже с lock?

Код в студию!
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764171
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAНемоКэп42пропущено...

А если второй начал писать в файл раньше, но без lock, а первый дошёл до этого места и хочет писать тоже, но уже с lock? Я вот эту ситуацию спрашивал.До этого места, но уже с lock?

Код в студию!
Аааа! Понял! Кто первый попал в эту секцию, тот первый и заблокировал эту секцию.

Одновременно с lock и без lock это я тоже сглупил.



Меня смущает то, что почему-то lock делается на объекте, а блокируется секция кода. А зачем объект-то нужен, если он сам по себе не блокируется? В примерах с МСДНа объект thisLock вообще непонятно, для чего нужен - как будто lock'у надо сфокусироваться именно на каком-то объекте, но блокирует он УЧАСТОК КОДА. Зачем thisLock нужен, если он в этом участке кода даже не участвует?
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764173
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для меня было бы логично, что блокируется именно объект, который используется в заблокированном участке кода.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764174
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот этот комментарий вообще убивает всю логику во мне. Т. е. объект под lock'ом не блокируется! Т. е. с помощью lock вообще нельзя защитить данные от одновременного изменения!

Похоже, что МС выбрала неудачную семантику для своей конструкции с lock, потому что более половины народу в той теме на SO, похоже, понимает под lock(thisLock) именно как защиту thisLock от изменения другими потоками, пока исполняется секция lock.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764178
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сразу второй вопрос. Как сделать так, чтобы при изменении коллекции IEnumerable в одном потоке, в другом потоке нормально прошла операция энумерации по этой коллекции? А то постоянные ошибки "Collection was modified; enumeration operation may not execute". При этом мне важен порядок следования, т. е. всякие ConcurrentBag не подходит.

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

У меня идея, что ни одна коллекция из ConcurrentCollections тут не подходит. Похоже, что надо делать свой вариант, где хранить каждое состояние коллекции в виде отдельной копии. Скажем, Queue<List<double>>. Тогда при каждом изменении коллекции записывать её в очередь тем потоком, который изменяет эту коллекцию, а другим потоком, который считывает эту коллекцию, делать Enqueue.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764195
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42понимает под lock(thisLock) именно как защиту thisLock от изменения другими потоками, пока исполняется секция lock.
Учитывая, что в 90% случаев thisLock объявляется как
Код: c#
1.
object thisLock = new object();


вышеописанное понимание более чем странное. Что они собрались изменять в экземпляре pure object?
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764231
НемоКэп42
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныНемоКэп42понимает под lock(thisLock) именно как защиту thisLock от изменения другими потоками, пока исполняется секция lock.
Учитывая, что в 90% случаев thisLock объявляется как
Код: c#
1.
object thisLock = new object();


вышеописанное понимание более чем странное. Что они собрались изменять в экземпляре pure object?
Тогда зачем нужно писать lock(thisLock)? Зачем для запирания кода нужен какой-то объект, который в этом коде не участвует?
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764256
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42Тогда зачем нужно писать lock(thisLock)? Зачем для запирания кода нужен какой-то объект, который в этом коде не участвует?
Затем, что блокировка накладывается на вполне определенный объект (более того, объектов для lock вполне может быть более одного). После наложения блокировки остальные потоки ждут освобождения, чтобы после её получения иметь возможность выполнять код (критическую секцию) далее. В принципе, конструкты с lock вполне можно переписать с использованием мониторов - возможно, так станет понятнее.
P.S. Изучите: http://www.albahari.com/threading/part2.aspx#_Locking
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764313
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныВ принципе, конструкты с lock вполне можно переписать с использованием мониторов
Ну и да, кстати:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
namespace test
{
  class Program
  {
    readonly object _lock = new object();
    void Test()
    {
      lock(_lock)
        Console.WriteLine("lock");
    }
    static void Main()
    {
      new Program().Test();
      Console.WriteLine("done");
      Console.ReadKey(true);
    }
  }
}


Метод Test() компилируется в
Код: plaintext
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.
.method private hidebysig instance void  Test() cil managed
{
  // Code size       40 (0x28)
  .maxstack  2
  .locals init ([0] bool '<>s__LockTaken0',
           [1] object CS$2$0000)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  .try
  {
    IL_0002:  ldarg.0
    IL_0003:  ldfld      object test.Program::_lock
    IL_0008:  dup
    IL_0009:  stloc.1
    IL_000a:  ldloca.s   '<>s__LockTaken0'
    IL_000c:  call       void [mscorlib]System.Threading.Monitor::Enter(object,
                                                                        bool&)
    IL_0011:  ldstr      "lock"
    IL_0016:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_001b:  leave.s    IL_0027
  }  // end .try
  finally
  {
    IL_001d:  ldloc.0
    IL_001e:  brfalse.s  IL_0026
    IL_0020:  ldloc.1
    IL_0021:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
    IL_0026:  endfinally
  }  // end handler
  IL_0027:  ret
} // end of method Program::Test
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764406
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42Тогда зачем нужно писать lock(thisLock)? Зачем для запирания кода нужен какой-то объект, который в этом коде не участвует?Срочно в Гугл читать про "монитор Хоара".
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764418
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НемоКэп42Для меня было бы логично, что блокируется именно объект, который используется в заблокированном участке кода.Простите, но с логикой у Вас слабовато. Впрочем как и у многих новичков.

У Вас вылетает исключение "Collection was modified; enumeration operation may not execute", которое явно говорит о том, что в процессе того как поток #1 читал данные, поток #2 изменил коллекцию и #1 не может продолжить чтение.

Даже если бы lock работал по Вашей логике, то чтобы от этого изменилось?
Поток #1 "замрёт", пока #2 изменяет коллекцию, "отомрёт" и возникнет таже самая ситуация: "Collection was modified; enumeration operation may not execute".

Вместо того, чтобы фантазировать, Вам следует прочитать комментарий от Pallaris ( 16647244 ) и заключить фрагмент кода чтения, и фрагмент кода изменения коллекции в
Код: c#
1.
2.
3.
4.
lock (одинИтотЖеObject)
{
   // Кусок кода
}
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764420
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAПростите, но с логикой у Вас слабовато. Впрочем как и у многих новичков.Не хамите.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764425
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvskyANAПростите, но с логикой у Вас слабовато. Впрочем как и у многих новичков.Не хамите.Свеном, отвали, не тебе меня манерам учить.
...
Рейтинг: 0 / 0
Как именно происходит блокировка (lock)?
    #38764435
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAНемоКэп42Для меня было бы логично, что блокируется именно объект, который используется в заблокированном участке кода.Простите, но с логикой у Вас слабовато. Впрочем как и у многих новичков.

У Вас вылетает исключение "Collection was modified; enumeration operation may not execute", которое явно говорит о том, что в процессе того как поток #1 читал данные, поток #2 изменил коллекцию и #1 не может продолжить чтение.

Даже если бы lock работал по Вашей логике, то чтобы от этого изменилось?
Поток #1 "замрёт", пока #2 изменяет коллекцию, "отомрёт" и возникнет таже самая ситуация: "Collection was modified; enumeration operation may not execute".

Вместо того, чтобы фантазировать, Вам следует прочитать комментарий от Pallaris ( 16647244 ) и заключить фрагмент кода чтения, и фрагмент кода изменения коллекции в
Код: c#
1.
2.
3.
4.
lock (одинИтотЖеObject)
{
   // Кусок кода
}

Тогда поток #2 подождёт пока поток #1 прочитает коллекцию, прежде чем её изменять.
Ну или наоборот: #1 подождёт пока #2 изменит коллекцию, прежде чем читать. В зависимости от того, кто первый начнёт выполнять свой кусок кода.
...
Рейтинг: 0 / 0
25 сообщений из 38, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как именно происходит блокировка (lock)?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]