Я немного запутался. Правильно, ли я понял, что если код лочит объект в одном потоке, то в этом же потоке этот же объект можно лочить сколь угодно много. ПО крайней мере код
lock(_client)
{
lock(_client)
{
}
}
работает нормально. То есть lock начнет работать, если использующий его код находится в разных потоках? По такой же схеме, как я понял работает и Monitor. Это так задумано, или я чего-то не понимаю?
Здравствуйте, Аноним, Вы писали:
А>Я немного запутался. Правильно, ли я понял, что если код лочит объект в одном потоке, то в этом же потоке этот же объект можно лочить сколь угодно много. ПО крайней мере код А>
А>работает нормально.
Это верно
А>То есть lock начнет работать, если использующий его код находится в разных потоках?
Этот вопрос(если это вопрос) не понятен.
А>По такой же схеме, как я понял работает и Monitor.
Да, lock это и есть Monitor.Enter + Monitor.Exit
Это так задумано, или я чего-то не понимаю?
Что именно? Я точно ничего не понимаю в Вашем вопросе
Homo Guglens
Re[2]: Простой вопрос про lock
От:
Аноним
Дата:
14.07.09 07:57
Оценка:
Здравствуйте, Nuseraro, Вы писали:
N>Здравствуйте, Аноним, Вы писали:
А>>Я немного запутался. Правильно, ли я понял, что если код лочит объект в одном потоке, то в этом же потоке этот же объект можно лочить сколь угодно много. ПО крайней мере код А>>
А>>работает нормально. N>Это верно
А>>То есть lock начнет работать, если использующий его код находится в разных потоках? N>Этот вопрос(если это вопрос) не понятен.
А>>По такой же схеме, как я понял работает и Monitor. N>Да, lock это и есть Monitor.Enter + Monitor.Exit
N>Это так задумано, или я чего-то не понимаю? N>Что именно? Я точно ничего не понимаю в Вашем вопросе
Я всегда думал, что для lock-а все-равно в каком потоке он используется. То есть, если вызывается lock для объекта, а тот уже был залочен, то lock тупо приостанавливает выполнения потока, пока объект не освободится. То есть код выше должен вести к DeadLock-у. Так как первый лок лочит объект и второй уже не может к нему получить доступ (пока не разлочится первый), а этого не случится, так как они в одном потоке. Но судя по всему lock учитывает поток, в котором он находится.
Вопрос мой был в следующем: это нормальное поведение lock-а, что не происходит деадлока, когда один и то же объект лочится в одном потоке (последовательно)?
Re: Простой вопрос про lock
От:
Аноним
Дата:
14.07.09 08:03
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Я немного запутался. Правильно, ли я понял, что если код лочит объект в одном потоке, то в этом же потоке этот же объект можно лочить сколь угодно много. ПО крайней мере код А>
А>работает нормально. То есть lock начнет работать, если использующий его код находится в разных потоках? По такой же схеме, как я понял работает и Monitor. Это так задумано, или я чего-то не понимаю?
В догонку еще такой вопрос. Как я понял, если для синхронизации всех потоков используется только один объект синхронизации (объект1), то DeadLock нельзя получить вообще никаким способом. Это так? То есть дедлок возможен только когда первый поток залочил объект1 и хочет залочить объект2, а второй поток наоборот, залочил объект2 и хочет залочить объект1.
Здравствуйте, <Аноним>, Вы писали:
А> Я всегда думал, что для lock-а все-равно в каком потоке он используется. То есть, если вызывается lock для объекта, а тот уже был залочен, то lock тупо приостанавливает выполнения потока, пока объект не освободится. То есть код выше должен вести к DeadLock-у. Так как первый лок лочит объект и второй уже не может к нему получить доступ (пока не разлочится первый), а этого не случится, так как они в одном потоке. Но судя по всему lock учитывает поток, в котором он находится. А> Вопрос мой был в следующем: это нормальное поведение lock-а, что не происходит деадлока, когда один и то же объект лочится в одном потоке (последовательно)?
Абсолютно нормально. lock придумали, т.к. при паралельной работе с данными может произойти их искажение. В рамках одного потока в принципе невозможно работать с данными паралельно, а значит lock в рамках одного потока бессмысленен.
А> В догонку еще такой вопрос. Как я понял, если для синхронизации всех потоков используется только один объект синхронизации (объект1), то DeadLock нельзя получить вообще никаким способом.
Абсолютно верно.
А> Это так? То есть дедлок возможен только когда первый поток залочил объект1 и хочет залочить объект2, а второй поток наоборот, залочил объект2 и хочет залочить объект1.
Именно. А отсюда — мораль: договоритесь(сами с собой, с коллегами и т.д.) что мол ребята, если нам в участке кода требуется лочить объект1 И объект2 — лочим их строго в такой последовательности, и ни разу не наоборот!! После чего термин Дед-Лоцк можете спокойно забыть.
Re[2]: Простой вопрос про lock
От:
Аноним
Дата:
15.07.09 08:40
Оценка:
Здравствуйте, Аноним, Вы писали:
А> В догонку еще такой вопрос. Как я понял, если для синхронизации всех потоков используется только один объект синхронизации (объект1), то DeadLock нельзя получить вообще никаким способом. Это так? То есть дедлок возможен только когда первый поток залочил объект1 и хочет залочить объект2, а второй поток наоборот, залочил объект2 и хочет залочить объект1.
Нет конечно. Сам по себе один объект синхронизации никаких гарантий дать не может, а описанный Вами сценарий деадлока — наиболее очевидный, но далеко не единственный. Вот упрощённый до примитивизма пример, который, однако-же, наглядно демонстрирует ёще один распространённый сценарий деадлока:
public partial class Form1 : Form
{
public Form1()
{
MainContext = WindowsFormsSynchronizationContext.Current;
InitializeComponent();
}
public volatile Int32 LockedResource;
public static readonly object GlobalLock = new object();
private readonly SynchronizationContext MainContext;
private void ModifyResource(object State)
{
lock (GlobalLock)
{
LockedResource += 15;
}
}
private Thread _Thr;
private void ThreadFunc()
{
lock (GlobalLock)
{
if (LockedResource == 0)
{
MainContext.Send(ModifyResource, null);
}
else
{
LockedResource++;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
_Thr = new Thread(ThreadFunc);
_Thr.Start();
}
}
Пример, повторюсь, упрощённый, но различные вариации его в более сложных видах — не редкость. Вообще, единых правил, позволяющих полностью исключить деадлоки, не существует. Есть только общеизвестные рекомендации, как свести их вероятность к минимуму, главные из которых — внимательность и аккуратность