Здравствуйте, 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.