Информация об изменениях

Сообщение Re: внутренняя реализация std::mutex? от 17.05.2018 9:46

Изменено 17.05.2018 9:56 AlexGin

Re: внутренняя реализация std::mutex?
Здравствуйте, barney, Вы писали:

B>Интересно, как реализованы базовые примитивы мультипоточности в C++? Такие как mutex


B>насколько я понимаю, все базируется на атомарной test-and-set инструкции (которую я бы назвал fetch-and-set)

B>и spin_lock блокировке, которая выглядит примерно так:

B>

B>spin_outer:
B> cmp flag, 1
B> je spin_outer // waiting until 0

B>spin_inner:
B> test-and-set ax, flag //executed atomicly
B> // {
B> // mov ax, flag // fetch current value to ax
B> // mov flag, 1 // set flag to 1
B> // }

B> cmp ax, 1
B> jne spin_inner // if old value was 0

B> // now in critical section

B> call do_work

B> mov flag, 0 // clean flag
B>leave:


Примерно так.
Вот подобное в C/C++ синтаксисе:
http://anki3d.org/spinlock
вот подобное при использовании boost:
https://www.boost.org/doc/libs/1_61_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_spinlock

B>но это приводит не просто к простою потока, а постоянной нагрузке

+100500
Да, но предполагается, что проектировщик/разработчик это понимает и не будет сильно злоупотеблять этим.
То есть — между входом (s.lock()) и выходом (s.unlock()) — делаем что-то весьма короткое с общим ресурсом,
чтобы избежать блокировки
spinlock s;

s.lock();
// здесь делаем что-то элементарное!
s.unlock();


B>при использовании std::mutex для критической секции такого не наблюдается.


По критическим секциям — вот интересная статья (от нашего коллеги Павла Блудова):
http://rsdn.org/article/baseserv/critsec.xml
Автор(ы): Павел Блудов
Дата: 14.03.2005
В статье рассматриваются аспекты работы с критическими секциями, их внутреннее устройство и способы отладки

В конце — важные выводы:

— Код, ограниченный критическими секциями, лучше всего свести к минимуму.
— Находясь в критической секции, не стоит вызывать методы "чужих" объектов.


B>как же работает мютекс?


В отличие от критической секции, мьютекс — объект системного ядра (в том же Windows API).
Предположу, что там "ожидание" это не простой цикл в условным/переходом на метку, я передача управления стстемному диспетчеру потоков.
В этом случае, задача STL (std::mutex) будет сведена просто к вызову соответствующих системных методов WinAPI или Posix.
Re: внутренняя реализация std::mutex?
Здравствуйте, barney, Вы писали:

B>Интересно, как реализованы базовые примитивы мультипоточности в C++? Такие как mutex


B>насколько я понимаю, все базируется на атомарной test-and-set инструкции (которую я бы назвал fetch-and-set)

B>и spin_lock блокировке, которая выглядит примерно так:

B>

B>spin_outer:
B> cmp flag, 1
B> je spin_outer // waiting until 0

B>spin_inner:
B> test-and-set ax, flag //executed atomicly
B> // {
B> // mov ax, flag // fetch current value to ax
B> // mov flag, 1 // set flag to 1
B> // }

B> cmp ax, 1
B> jne spin_inner // if old value was 0

B> // now in critical section

B> call do_work

B> mov flag, 0 // clean flag
B>leave:


Примерно так.
Вот подобное в C/C++ синтаксисе:
http://anki3d.org/spinlock
вот подобное при использовании boost:
https://www.boost.org/doc/libs/1_61_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_spinlock

B>но это приводит не просто к простою потока, а постоянной нагрузке

+100500
Да, но предполагается, что проектировщик/разработчик это понимает и не будет сильно злоупотеблять этим.
То есть — между входом (s.lock()) и выходом (s.unlock()) — делаем что-то весьма короткое с общим (совместным) ресурсом,
чтобы избежать взаимной блокировки.

spinlock s;

s.lock();
// здесь делаем что-то элементарное!
s.unlock();


B>при использовании std::mutex для критической секции такого не наблюдается.


По критическим секциям — вот интересная статья (от нашего коллеги Павла Блудова):
http://rsdn.org/article/baseserv/critsec.xml
Автор(ы): Павел Блудов
Дата: 14.03.2005
В статье рассматриваются аспекты работы с критическими секциями, их внутреннее устройство и способы отладки

В конце — важные выводы:
— Код, ограниченный критическими секциями, лучше всего свести к минимуму.
— Находясь в критической секции, не стоит вызывать методы "чужих" объектов.


B>как же работает мютекс?


В отличие от критической секции, мьютекс — объект системного ядра (в том же Windows API).
Предположу, что там "ожидание" это не простой цикл в условным/переходом на метку, я передача управления стстемному диспетчеру потоков.
В этом случае, задача STL (std::mutex) будет сведена просто к вызову соответствующих системных методов WinAPI или Posix.