Программирование: введение в профессию. III: системы и сетиАннотацияВ третий том книги «Программирование: введение в профессию» вошли части V–VIII. В части V рассматриваются системные вызовы для ввода-вывода, управление процессами, механизмы взаимодействия процессов, такие как сигналы и каналы, а также понятие терминала и связанные с ним явления, в том числе сеансы и группы процессов, виртуальные терминалы, управление дисциплиной линии. Часть VI посвящена компьютерным сетям; даётся небольшой обзор протоколов, используемых в сети Интернет, рассмотрена подсистема сокетов и событийно-ориентированное построение серверных программ. В части VII рассматриваются вопросы, связанные с разделяемыми данными, критические секции, взаимоисключение; даются базовые сведения о библиотеке pthread. Часть VIII содержит ряд сведений о внутреннем устройстве операционной системы; в частности, рассматриваются различные модели виртуальной памяти, подсистема ввода-вывода и т.п. Публикация в бумажном вариантеОпубликовано издательством МАКС Пресс (Москва) в 2017 году. ISBN 978-5-317-05606-3. Электронная версияЭлектронная версия, идентичная печатному изданию, доступна здесь: http://www.stolyarov.info/books/pdf/progintro_vol3.pdf Статус бумажной версииВ настоящее время может быть приобретена в здании факультета ВМК, а также заказана с доставкой на этом сайте. Архив примеров программАрхив, содержащий примеры программ из первых трёх томов, можно скачать здесь: http://www.stolyarov.info/books/extra/progintro_vol123_examples.tgz Напоминаем, что раскрыть этот архив можно командой tar -xzf progintro_vol123_examples.tgz |
Программирование: введение в профессиюпояснениеВы находитесь на официальном сайте Андрея Викторовича Столярова, автора учебных пособий по программированию и информационным технологиям. Если вы искали сайт замечательного писателя-фантаста Андрея Михайловича Столярова, то вам, к сожалению, не сюда. Андрей Михайлович Столяров в библиотеке Мошкова |
☞ From PowerSlave (unverified) Tue Jun 29 20:13:00 2021 UTC
Здравствуйте. У
Здравствуйте. У меня проблема с запуском X-сервера и xterm в нём. На 28-й странице у вас об этом написано.
Суть в том, что, когда я запускаю X-сервер на дисплее 1, то он явно запускается, но никакого фона и курсора нет. Просто чёрный экран. Когда я нажимаю Ctrl-Alt-F1, ввожу DISPLAY=:1 xterm, а затем нажимаю Alt-F7, переключение происходит на дисплей 0, а дисплей 1 снова открывается только если я убью процесс с этим xterm-ом. В чём может быть дело?
ответить
From admin Wed Jun 30 09:09:49 2021 UTC
Что-то у меня
Что-то у меня ощущение, что вы путаете "дисплеи" в смысле X Window и виртуальные консоли, у которых нумерация своя.
В принципе любой X-сервер может быть запущен на любой виртуальной консоли и при этом иметь любой номер дисплея, т.е. номер вирт.консоли никак не связан с номером дисплея. На 7-й консоли у вас, видимо, штатный X-сервер, запускаемый вашим дистрибутивом линукса или что у вас там. Если так, то, скорее всего, тот X-сервер, который запускаете вы (вручную, как 1-й дисплей) берёт себе 8-ю консоль, так что переключаться на него (с любой из текстовых консолей) следует по Alt-F8. Непонятно только, почему это не происходит само собой. Но вообще это всё напоминает "диагноз по фотографии", сложно сказать, что там у вас такое происходит, не видя машины.
ответить
☞ From Anonymous (unverified) Sat Apr 24 19:06:00 2021 UTC
Андрей
Андрей Викторович, на странице 176 - "маршрутизация для Дмитрия" - случайно, не пропущен маршрут для связи с "12-й сеткой", что-то вроде 192.168.12.0/24 -> 192.168.14.1? Или это я туплю )))
ответить
From admin Sat Apr 24 19:29:21 2021 UTC
А зачем? Там уже
А зачем? Там уже есть 0.0.0.0/0 -> 192.168.14.1, "12я сетка" ни фига не особенная :-)
ответить
☞ From kravcneger Wed Mar 17 18:39:00 2021 UTC
стр 219
Здравствуйте, Андрей Викторович.
На странице 219 в листинге кода отсутствует вызов listen, чтобы сделать сокет слушающим.
ответить
From admin Wed Mar 17 20:24:40 2021 UTC
В новом издании
В новом издании уже исправлено.
ответить
☞ From Давид (unverified) Sat Feb 20 10:48:00 2021 UTC
Здравствуйте,
Здравствуйте, стр. 84.
> приводят к системному вызову _exit
Здесь и до этого так же упоминался "системный вызов" _exit. Но судя по открытым исходникам линукса, системный вызов всё-таки называется просто exit, ну или exit_group как указано в сноске, а _exit - это обертка из стандартной библиотеки.
ответить
From admin Sat Feb 20 12:17:14 2021 UTC
Кончайте
Кончайте бредить. exit без подчёркивания — это (документированно!) библиотечная функция, которая, прежде чем завершить программу (то есть обратиться к ядру системы), вызывает ещё все хуки, которые были навешаны на неё функцией atexit (читайте man 3 atexit). Этим пользуется подсистема "стандартного" ввода-вывода, чтобы вытеснить буфера.
_exit с подчёркиванием — это официальное название системного вызова, который, если интересно, в Linux/i386 и FreeBSD/i386 имел номер 1.
К сожалению (именно к сожалению — я бы сказал, к величайшему, поскольку это одно из свидетельств безнадёжной деградации IT-индустрии) "современные" версии "стандартной" библиотеки, поддерживающие (читай -- заточенные) на мультитрединг (относительно которого я говорил, говорю и буду говорить, что применять его недопустимо -- никогда и ни для чего), предпочитают завершать процесс вызовом exit_group, для чего функция с названием _exit там представляет собой не обёртку для соответствующего системного вызова, а простую функцию, которая — ага — вызывает exit_group. Факта существования системного вызова _exit это никак не отменяет. Аналогичная ситуация была, например, с вызовом signal: ядро такой вызов поддерживало, но одноимённая библиотечная функция вместо "своего" вызова обращалась к sigaction. Вот вам, кстати, цитата из man 2 _exit:
NB: если НЕ использовать мультитрединг (а я всё-таки надеюсь, что мои читатели не станут пополнять ряды безмозглых макак, которые его применяют), семантика библиотечной функции _exit ничем не отличается от семантики классического системного вызова _exit.
ответить
☞ From Константин (unverified) Sat Feb 20 05:16:00 2021 UTC
Текущий каталог процесса-демона
Андрей Викторович, здравствуйте, прошу разъяснить небольшой момент. На странице 146 вначале сказано что "При старте демона принимаются меры, чтобы его функционирование не мешало работе и администрированию системы.Так, текущий каталог обычно меняется на корневой, чтобы не мешать системному администратору при необходимости удалять каталоги, монтировать и отмонтировать диски и т.п." Этот момент остался мне не понятен, прошу пояснить каким образом текущий рабочий каталог процесса-демона может помешать системному администратору?
ответить
From admin Sat Feb 20 06:45:14 2021 UTC
Попробуйте
Попробуйте как-нибудь на досуге примонтировать флешку, в соседнем терминале туда зайти, что-то там поделать с файлами, а потом про второй терминал забыть и в первом попытаться флешку отмонтировать.
Hint: будет ошибка "Device busy". Потому что нельзя отмонтировать файловую систему, внутри которой кто-то сидит, то есть в системе существует хотя бы один процесс, текущий каталог которого расположен внутри этой файловой системы.
Между прочим, это знает каждый, у кого основным инструментом работы с компьютером является командная строка. Это просто невозможно не знать, такая ситуация случается едва ли не каждый день в ходе обычной работы.
В предисловиях к моим книгам чётко сказано, что переход на *nix и командную строку — это обязательное условие для того, чтобы от книг был хоть какой-то толк. Не хотите переходить на *nix и командную строку — дело ваше, но хотя бы не тратьте время на мои книги, толку не будет всё равно.
ответить
From Константин (unverified) Sat Feb 20 11:37:00 2021 UTC
Спасибо
Спасибо за подробный ответ! Теперь всё стало ясно.
ответить
From admin Sat Feb 20 14:20:05 2021 UTC
Ну, вам-то может
Ну, вам-то может и стало ясно, зачем демоны chdir делают, а мне вот по-прежнему неясно, что вы на моём сайте забыли.
ответить
☞ From Иван (unverified) Fri Jan 29 07:56:00 2021 UTC
Опечатка
Здравствуйте, Андрей Викторович.
стр. 119 "при этом, ни с каким файлами они не связаны"
ответить
From admin Fri Jan 29 11:32:12 2021 UTC
В тексте книги
В тексте книги нет запятой после "при этом", в вашей цитате есть. Если вы считаете, что "опечатка" состоит в этом, то заблуждаетесь, поскольку запятая здесь не нужна.
ответить
From Anonymous (unverified) Sat Feb 13 06:56:00 2021 UTC
какимИ
"ни с какими файлами они не связаны"
Возможно, имелось ввиду отсутствие буквы "и" в слове "какими".
ответить
From admin Sat Feb 13 07:46:09 2021 UTC
Факт.
Да, спасибо. Я это ухитрился не заметить, глядя прямо на эту строчку.
ответить
☞ From Давид (unverified) Sat Jan 23 11:58:00 2021 UTC
Здравствуйте.
Здравствуйте. стр. 84.
> в составе выражения exit(main(0)).
Почему именно обертка exit? На ассемблере мы вызывали системный вызов _exit, правильнее ли было указать здесь _exit(main(0))?
ответить
From admin Sat Jan 23 21:19:00 2021 UTC
Нет, разумеется
Именно библиотечная функция exit. На досуге попробуйте вывод программы hello, world перенаправить в файл и осознайте, что если бы там был _exit, ваш файл остался бы пустым.
NB: нуля там никакого нет, откуда вы его взяли? Там просто
exit(main())
.ответить
From Давид (unverified) Sun Jan 24 09:33:00 2021 UTC
С нулем ошибся,
С нулем ошибся, да.
Исходя из exit(main()) - если внутри main мы используем exit(0) вместо return 0. Тогда с каким значением будет вызвана внешняя exit, если во время вызова внутреннего exit буфера очистятся и будет вызван системный вызов _exit, который завершит процесс?
ответить
From admin Sun Jan 24 12:47:00 2021 UTC
Если внутри main,
Если внутри main, а равно и в любом другом месте программы мы вызовем exit(хоть от нуля, хоть от чёрта лысого), то больше уже ничего вызвано не будет. Библиотечная версия exit отработает хуки, которые на неё понавешаны с помощью atexit (в большинстве программ это только вытеснение буферов высокоуровневого вывода, больше ничего), после чего сделает _exit, и на этом всё кончится. До этой вашей "внешней exit" управление не дойдёт.
Мне вот интересно, что у вас за каша в голове, если такие вопросы возникают. К сожалению, через комменты я это вряд ли определю, но что каша имеет место — это вообще без вариантов.
ответить
From Давид (unverified) Sun Jan 24 15:13:00 2021 UTC
> До этой вашей
> До этой вашей "внешней exit" управление не дойдёт.
Возвращаемся к выражению exit(main()). Если до "внешней exit" управление не дойдет, значит выражение exit(main()) само по себе не является обобщенным вариантом? Оно актуально только если main заканчивается через return и тогда управление таки дойдет до "внешней exit"?
Каши никакой нет, все достаточно подробно и грамотно расписано, чтобы она не появилась. Но, тем не менее, есть некоторые моменты, которые вызывают вопросы. При изучении любого нового материала может не до конца быть все понятно, обратная связь на то и нужна.
Так что отдельная благодарность за этот сайт.
ответить
From admin Sun Jan 24 16:49:00 2021 UTC
Простите, а что
Простите, а что такое "является обобщённым вариантом"? Или "не является обобщённым вариантом"? И вообще, что такое "обобщённый вариант"?
По существу вопроса: ну вот есть у вас, к примеру, две функции в программе, одна называется f, другая g, вы пытаетесь выполнить f(g()), только одна неприятность — g берёт, да и рушит всю программу. Ну, в смысле, завершает. Мне вот что интересно, вы понимаете, что в такой ситуации бессмысленно спрашивать, с каким значением параметра будет вызвана f, поскольку она уже не будет вызвана?
А каша в мозгу у вас есть, можете не сомневаться. Иначе мне бы не приходилось сейчас ломать голову над тем, откуда у вас выполз этот "обобщённый вариант" и что бы он такое значил. Вы, случайно, первый том и паскалевскую часть не пропустили? Обычно те, кто уже программировал, таких вопросов не задают.
ответить
From Давид (unverified) Sun Jan 24 17:57:00 2021 UTC
Нет, первый том
Нет, первый том я прочитал.
> вы понимаете, что в такой ситуации бессмысленно спрашивать, с каким значением параметра будет вызвана f, поскольку она уже не будет вызвана?
Именно, это само собой разумеется. Просто вот эта аналогия, когда мы выполняем f(g()), а функция g завершает программу,
должна быть тоже как-то отражена в строках книги. А то в выражении exit(main()) невольно подумаешь, что даже если main завершит преждевременно программу, exit все равно выполнится с кодом от main.
Это лишь уточнение. Возможно, его стоило бы включить в книгу. Может для кого-нибудь это тоже будет не столь очевидно, хотя как знать, воля Ваша.
> И вообще, что такое "обобщённый вариант"
Поясню, я имел в виду, что запись exit(main()) означает всегда сначала вызывается main, а потом в любом случае будет вызвана exit с кодом от main. Но, как мы разобрали, не всегда. Это я и хотел уточнить.
ответить
From admin Sun Jan 24 20:58:03 2021 UTC
Да прочитать-то
Да прочитать-то вы его, может, и прочитали, а на Паскале вы хоть что-нибудь полезное сделали? Паскаль же там излагается не для того, чтоб про него просто "прочитать", нужно наработать опыт работы на нём, иначе про него и рассказывать бесполезно.
А вот про функции — ну вот не вижу я логики в ваших словах. Совсем. Как что-то может быть вызвано "в любом случае", когда программа уже кончилась? Ну всё уже, нету её, завершилась, схлопнулась, больше не выполняется, как в ней что-то может быть ещё вызвано?
ответить
From Давид (unverified) Mon Jan 25 03:48:00 2021 UTC
Простите, а как
Простите, а как написание чего-то полезного на Паскале поможет при уточнении данного вопроса?
Согласен, возможно это уточнение и лишнее, но от опыта работы на Паскале в данном вопросе ни горячо, ни холодно.
ответить
From admin Mon Jan 25 15:30:43 2021 UTC
Если бы у вас
Если бы у вас был опыт работы на Паскале, ещё раз повторяю, вы бы таких вопросов не задавали, поскольку чувствовали бы на уровне интуиции, как именно происходит работа программы и что собой представляет её досрочное завершение. И, подчеркну, далеко не только это. Паскалю в моём курсе посвящена одна из самых крупных частей, и это отнюдь не для мебели.
Вообще говоря, если вы считаете мою методику обучения неправильной, то это ваше право, но мне не вполне понятно, что вы такого забыли на моём сайте. Есть другие сайты и другие преподаватели, которые с удовольствием помогут вам в стремлении пополнить ряды безмозглых обезьянок, почему-то именующих себя программистами.
ответить
From Давид (unverified) Mon Jan 25 17:48:00 2021 UTC
1. Ваш цикл я
1. Ваш цикл я нашел по рекомендациям и сходу же прямо с оглавления понравился именно подход, когда только Unix и стремление научить низкоуровневым вещам.
2. Книга по Паскалю очень классная. Намного лучше того, что мне преподавали когда-то в университете. То же самое касается и ассемблера с Си. Одна только глава про написание программы без использования стандартной библиотеки чего стоила.
3. Я еще не до конца дочитал про ОС, но даже то, что отдельная глава есть для параллельного программирования, уже выше всех похвал наряду с теми, что мне давали в университете.
4. Но самое главное, что сейчас это все доступно в бесплатном варианте и с живой поддержкой в виде как раз этого сайта.
Так что я не только не считаю методику неправильной, а наоборот, что это огромный клад ценной информации, который актуален до сих пор.
Вообще весь этот разговор из-за какого-то замечания, который вызвал некоторые вопросы. Никто не хотел и капли усомниться в Вашем труде.
ответить
From admin Mon Jan 25 18:39:00 2021 UTC
Короче говоря,
Короче говоря, мой вердикт как преподавателя тут такой. Если хотите чему-то научиться — берите в руки Free Pascal и пишите какую-нибудь текстовую (но при этом полноэкранную) игрушку. Желательно не такую, какая уже есть, а собственного изобретения. Когда найдётся кто-нибудь, кто добровольно (а не потому что вы его слёзно умоляли) на вашу игрушку потратит хотя бы минут десять — считайте, что тему Паскаля вы для себя раскрыли.
Желательно потом ещё и на ассемблере что-то подобное сотворить, но там я, конечно, не ожидаю, что вы что-то полноэкранное изобразите. Ну хоть что-то, какую-то сколько-нибудь полезную программу сделать крайне желательно: это ваш первый и последний шанс обрести опыт на асме, потом (в течение всей жизни, увы) на это никогда не будет времени, поверьте моему опыту.
И вот только после этого возвращайтесь к изучению Си. Тогда (и не раньше) вы будете к этому готовы.
NB: последовать этому совету или нет — дело ваше. Но если решите, что нет — то хотя бы не тратьте время на мои книжки, толку всё равно не будет.
UPD: Я вынужден подчеркнуть ещё раз: я не считаю, что вы готовы к освоению Си, и отвечать на ваши вопросы по Си более не буду. Ваш очередной комментарий раскрыт не будет. NB: из текста вашей очередной пачки "вопросов" видно, что в мозгах у вас не просто каша, там просто треш и угар. Что делать — я вам уже сказал. Хотите — делайте, не хотите — не делайте, но ищите тогда других учителей.
ответить
From Давид (unverified) Tue Jan 26 02:23:00 2021 UTC
Спасибо за
Спасибо за советы.
ответить
From nelson Wed Jan 27 13:02:08 2021 UTC
Паскаль
от опыта работы на Паскале в данном вопросе ни горячо, ни холодно.
Почему? Опыт же приобретаете. На Паскале можно писать хороший качественный софт в отличие от языков скриптовых поделок с помощью которых "обучают" на говнокурсах. То, что он "непопулярен", ни о чём не говорит. И не смотрите на все эти "рейтинги популярности ЯП". Они составляются фиг пойми кем и представляют собой лютую дичь, представляющую собой кучу совершенно разных ЯП, которые даже и сравнивать по-хорошему нельзя.
ответить
☞ From Давид (unverified) Mon Jan 11 19:38:00 2021 UTC
Здравствуйте.
Здравствуйте. Возможные опечатки на страницах 60-61.
> процесс, выполняющий вызов, должен иметь euid, равный 0
> указанный третьим параметром gid должен либо быть равен euid'у
В первом случае должен быть uid.
Во втором - gid.
И в слове "параметром" буква пропущена.
ответить
From admin Mon Jan 11 22:22:00 2021 UTC
В первом случае
В первом случае должен быть именно euid -- effective uid, именно он определяет полномочия.
Во втором должен быть egid, а не euid, как там написано; это уже известная опечатка.
А вот про "парметром" -- спасибо большое, и корректор это прощёлкал, и сам я проглядел, хотя совсем недавно редактировал этот кусочек.
ответить
☞ From Давид (unverified) Sat Jan 9 05:26:00 2021 UTC
Здравствуйте,
Здравствуйте, страница 39.
> уже на основе информации из /etc/groups
Разве не /etc/group?
ответить
From admin Sat Jan 9 06:13:00 2021 UTC
Абсолютно
Абсолютно верно, спасибо! Вовремя.
ответить
☞ From Anonymous (unverified) Fri Jan 8 22:26:00 2021 UTC
Остановился на
Остановился на половине, большая часть что до этого момента было – описания всевозможных функций и никаких подсказок закрепить их какой-то практиой. Предполагается что читатель должен штрудировать эти функции и ждать когда под конец книги напишут «кхм, ну теперь напишите простенький сервер»?
ответить
From admin Sat Jan 9 06:20:46 2021 UTC
Книга написана
Книга написана в предположении, что читателю этот материал интересен. В этом случае любой предложенный инструмент вызывает мысли вроде "а теперь я, наверное, могу вот это и вот то", всё тут же хочется попробовать, и задачи для этого придумываются сами собой. Во всяком случае, когда я программировать учился, со мной происходило именно так, и всевозможные задания только мешали, хотелось делать исключительно то, что хочется самому.
Судя по тому, сколь настойчиво публика требует от меня задачник, так получается не у всех. В общем и целом, задачник стоит в планах, я даже начал его писать, но сейчас всё-таки сначала хочется добить второе издание.
ответить
☞ From Anonymous Octopus (unverified) Fri Nov 20 16:08:00 2020 UTC
Добрый
Добрый день!
Меня смущает пример в спящем парикмахере с размещением up(customers) после критической секции в функции клиента (последний абзац стр. 287). Смущение, возможно, наличествует из-за недостатка понимания, но я, тем не менее, его тут обозначу.
Следуя схожей логике можно вообразить, что в при правильной реализации одновременно заходят два клиента, один проходит критическую секцию и откачивается на диск не встав на блокировку перед lock(barber). В это же время на seat_mutex заблокированы второй клиент и уже проснувшийся брадобрей. Допустим первым разблокируется второй клиент и с ним, вот незадача, происходит то же самое, что с первым - он откачивается на диск. Дальше брадобрей уже наконец попадает в критическую секцию (уже свою, но тоже по seat_mutex) и так же, как в примере неправильно реализации, дважды вхолостую делает работу до того, как оба клиента сделают CUSTOMER_WORK.
Вы могли бы мне указать, где я не прав?
ответить
From admin Sat Nov 21 00:58:44 2020 UTC
ох уж этот парикмахер
Это вот, случайно, не та же самая проблема?
http://www.stolyarov.info/guestbook/archive/3#comment-2797
ответить
From Anonymous Octopus (unverified) Mon Nov 23 14:01:00 2020 UTC
парикмахер - тот ещё перец
Как минимум из той же оперы.
Спасибо, буду теперь иметь в виду возможность заглянуть в гостевую книгу - в конце-концов, не один же я такой непонятливый!
ЗЫ: не по теме, но о наболевшем - капчи у Вас тут зубодробительные!
ответить
From admin Mon Nov 23 15:59:20 2020 UTC
Про капчу --
Про капчу -- если зарегистрироваться, то залогиненным пользователям капчу не показывают. Один раз при регистрации преодолеете -- и всё.
ответить
☞ From mondrew (unverified) Tue Nov 10 07:23:00 2020 UTC
7.4.2 Создание дополнительного файла
На стр.302 предлагается создать файл foobar.dat.lock с использованием флага O_EXCL, а в листинге программы на стр.303 в системном вызове open этот флаг не используется (вместо него используется O_CREAT).
ответить
From admin Tue Nov 10 15:09:59 2020 UTC
Есть такое, уже
Есть такое, уже поймали. Спасибо за внимательность.
ответить
☞ From mondrew (unverified) Sat Nov 7 15:12:00 2020 UTC
Семафоры Дейкстры
На стр.264 есть противоречие в следующем предложении:
"Операция down должна, наоборот, уменьшать значение на 1, но сделать это она может только когда текущее значение строго больше нуля, ведь значение семафора не может быть отрицательным."
А как же ноль?
ответить
From admin Sat Nov 7 15:26:59 2020 UTC
Ну так если
Ну так если семафор уже равен нулю, его уменьшить дальше нельзя — в минус уйдёт, а ему запрещено. Там в тексте это вроде написано всё, в этом случае down приводит к блокировке (ради неё, собственно, семафоры и придуманы).
ответить
☞ From Anonymous (unverified) Mon Oct 26 10:57:00 2020 UTC
Получаю
Получаю странные результаты работы программы prod_cons. Программа была запущенна 100 раз в цикле c двумя текстовыми файлами на входе.
Содержимое первого файла:
3.14 0.234234234 12341.2323525
Содержимое второго файла:
1241241.11112444 234234.22344 34345345 345345
В 93 из 100 случаев результат был следующий:
total average: 9.373352 (sum = 65.613466; count = 7)
В остальных же:
total average: 10.744874 (sum = 64.469243; count = 6)
total average: 8.810194 (sum = 52.861167; count = 6)
total average: 8.596974 (sum = 51.581843; count = 6)
total average: 8.596974 (sum = 51.581843; count = 6)
total average: 8.810194 (sum = 52.861167; count = 6)
total average: 10.744874 (sum = 64.469243; count = 6)
total average: 8.596974 (sum = 51.581843; count = 6)
ответить
From admin Mon Oct 26 20:34:00 2020 UTC
В общем даже
В общем даже понятно, почему. Программа завершается, если видит, что все производители завершились. При этом никто не проверяет, что буфер опустел, и тем более никто не проверяет, нет ли у консьюмеров ещё чего-то "недоскинутого".
Вообще, конечно, вот прямо классический race condition. Надо будет подумать, что с этим можно сделать.
UPD: Всё оказалось ещё проще. В той версии, которая в книжке, консьюмер, если не может сразу заполучить grand_mutex, плюёт на это дело и оставляет информацию в своих локальных переменных. Если он сюда придёт ещё раз, то всё будет хорошо (ибо он тогда всю инфу сразу сольёт), вот только он же может больше сюда и не прийти -- числа кончатся, он повиснет на sem_wait(&buf_full), потом процесс завершится вместе со всеми тредами.
Что называется, хотел один такой (то есть я) продемонстрировать неблокирующий вариант захвата мьютекса, а получилась в итоге полная хрень. Это легко скорректировать, если при наличии локальной инфы опускание семафора тоже сделать неблокирующим, типа, если в основную секцию не пустили, а у меня есть что скинуть, то я хотя бы в секцию по grand_total попробую снова пойти. Но наглядность текста примера после этого упадёт резко, то есть там будет вообще непонятно, что происходит. Так что, видимо, придётся try_lock выкинуть из примера.
ответить
From Anonymous (unverified) Mon Oct 26 22:21:00 2020 UTC
Спасибо за
Спасибо за пояснение и неожиданный пример race condition :)
ответить
☞ From Антон (unverified) Sat Oct 10 16:21:00 2020 UTC
На страницах
На страницах 262-263 нет никакой путаницы с числами 0 и 1, представляющими открытый и закрытый мьютекс? В самом верхнем сниппете кода на 263 стр lock и unlock должны будут работать как задумано только если 0 - "открыто", 1 - "закрыто". Сейчас, например, получается, что unlock закрывает мьютекс (а не открывает), присваивая ему 0, потому что, как на предыдущей странице было сказано, 0 соответствует состоянию закрытого мьютекса
ответить
From admin Sat Oct 10 17:41:19 2020 UTC
Ухххххх!
Есть, конечно. Ещё как есть. Сейчас посмотрел — стало грустно.
Спасибо за внимательность — на эту ахинею до вас никто внимания не обратил, так что она чуть было не проползла во второе издание.
ответить