-
lock
описан и в справке паскаля. Другим ресурсам по паскалю в интернете доверять не стоит. Они скорее будут описывать какой то другой паскаль, к примеру дельфи.
- Из ресурсов, которым можно доверять - я знаю только msdn (справка) и StackOverflow (форум типа вопрос-ответ). На них вы вряд ли найдёте паскаль, надо искать для C#. А так как C# это чистый .Net без примесей - практически всё сказанное о нём будет правдой и о данном паскале (ибо он является надстройкой на .Net).
Вот соответствующая страница msdn:
Теперь моё объяснение:
Любого не_размерного.
Обычно в lock
используют или объект полученный через new object
, или объект который всё равно участвует в операции.
К примеру:
begin
var otp_lock := new object;
System.Threading.Thread.Create(()->
while true do// lock otp_lock do
begin
writeln(1);
end).Start;
System.Threading.Thread.Create(()->
while true do// lock otp_lock do
begin
writeln(2);
end).Start;
end.
writeln
кидает текст в вывод 2 кусками: сам текст (2
превращается в '2'
) и знак переноса строки.
Поэтому если вы запустите этот код - в некоторых местах перенос строки будет пропущен, а в некоторых их будет 2.
Если раскомментировать lock
- это перестанет происходить, потому что lock
объекта otp_lock
запрещает все действия с этим объектом в других потоках. И другая блокировка тоже считается за действие с ним. Поэтому хоть 2 вызова writeln
и находятся в разных потоках - они никогда не будут выполнены одновременно.
А в данном случае - у нас уже есть объект, поэтому new object
создавать не обязательно:
begin
var l := new List<integer>;
System.Threading.Thread.Create(()->
while true do
begin
for var i := 1 to 10 do
lock l do l.Add(i);
lock l do l.Clear;
end).Start;
System.Threading.Thread.Create(()->
while true do
begin
lock l do
begin
l.Println;
Sleep(200);
l.Println;
writeln('-'*50);
end;
Sleep(300);
end).Start;
end.
Список является особо примечательным примером, потому что он даёт жуткие ошибки, если вы попробуете добавить/убрать элемент когда идёт перечисление элементов (для вывода .Println
, разумеется, проходит по всем элементам).
Поэтому если убрать lock
- у вас рандомно (не обязательно на первом выводе) вылетит ошибка “коллекция изменена”. Это 1 из самых сложно вылавливаемых ошибок в многопоточности, но все они примечательны тем - что являются плавающими, то есть не обязательно воспроизводятся если выполнить те же действия в том же порядке.