Да не клонируются сокеты/файлы для потоков.
Это один сокет. А то что вы наблюдаете — обычный race condition.
Вообще насколько я помню нигде не гарантируется что операции над дескрипторами потокобезопасны.
Так что так как у вас в первом примере делать вообще нельзя.
Он подвисает не потому что закрытие сокета в одном из потоков не видно в другом потоке, а потому что конкуретные операции из разных потоков на одном сокете в линуксе сериализуются мьютексом, и сама операция read достаточно длительная, чтобы оба потока успели вызвать read до того как первый из них вызовет close.
Уберите конкуренцию потоков и увидите что с сокетами все точно также как и с файлами:
Если один из потоков решает закрыть свой сокет, другие потоки об этом ничего не знают, поскольку они на самом деле отдельные процессы и у них свои собственные копии этого сокета, и продолжают работать.
И процитирванное совершенно не соответствует действительности.
Формулировка другая, но в применении к данному вопросу она дает то же результат.
То что раньше называлось точками следования (sequence point), теперь называется упорядочиванием (sequencing). Что по сути является тем же самым, только позволяет еще описывать поведение неупорядоченного (unsequenced) кода.
Т.е. когда мы говорим что два выражения упорядочены это то же самое что в старом стандарте что между выражениями есть точка следования.
Таким образом интрепретация нового текста стандарта в старых терминах такая:
every value computation and side effect
associated with any argument expression, or with the postfix expression designating the called function, is
sequenced before execution of every expression or statement in the body of the called function
Это означает существует точка следования между вычислением всех аргументов функции и ее непосредственно выполнением.
Таким образом как старом так и в новом стандарте, вычисление аргументов для двух последовательно идущих в коде функций производится раздельно (если сами вызовы между собой упорядочены, как в данном случае).
Дело в том, что хотя стандарт и гарантирует, что process() будет вызвана перед print_result(), но не гарантируется, что перед аргумент функции print_result будет вычислен после выполнения process().
Вы ошибаетесь.
Стандарт гарантирует следующее:
When calling a function (whether or not the function is inline), there is a sequence point after the evaluation
of all function arguments (if any) which takes place before execution of any expressions or statements in
the function body. There is also a sequence point after the copying of a returned value and before the execution
of any expressions outside the function11)
Таким образом аргументы второй функции не могут быть вычислены до аргументов первой, т.к. они разделены двумя точками следования (sequence point).
Потому что мейнтейнер PulseAudio, Леннарт Поттеринг — криворукий е#лан.
При внесении новых фич не только не заботился об обратной совместимости, но даже считал это достоинством пульса.
Пруф я уже приводил:
Если бы сокет был склонирован, то данный код подвисал бы на втором read().
Это один сокет. А то что вы наблюдаете — обычный race condition.
Вообще насколько я помню нигде не гарантируется что операции над дескрипторами потокобезопасны.
Так что так как у вас в первом примере делать вообще нельзя.
Уберите конкуренцию потоков и увидите что с сокетами все точно также как и с файлами:
И процитирванное совершенно не соответствует действительности.
Проверка:
Выводит:
Т.е. дескриптор текущего потока, закрытый в другом потоке, закрыт и в текущем.
LO умеет открывать PDFы им же экспортированные.
Там можно подправить текст и экспортировать обратно.
Инициализировать через atomic_compare_exchange_strong_explicit, а читать через atomic_load
Правда надо признать, shared_ptr тут не нужен. Можно обойтись простым указателем :)
Как?
Уже смеются — например в сериале «Хорошая жена» хорошо так посмеялись над нелепостью такого устройства :)
www.youtube.com/watch?v=N9TpHGLj0yA
Пойду перечитаю стандарт :)
См. мой ответ habrahabr.ru/post/215059/#comment_7385513
То что раньше называлось точками следования (sequence point), теперь называется упорядочиванием (sequencing). Что по сути является тем же самым, только позволяет еще описывать поведение неупорядоченного (unsequenced) кода.
Т.е. когда мы говорим что два выражения упорядочены это то же самое что в старом стандарте что между выражениями есть точка следования.
Таким образом интрепретация нового текста стандарта в старых терминах такая:
Это означает существует точка следования между вычислением всех аргументов функции и ее непосредственно выполнением.
Таким образом как старом так и в новом стандарте, вычисление аргументов для двух последовательно идущих в коде функций производится раздельно (если сами вызовы между собой упорядочены, как в данном случае).
Вы ошибаетесь.
Стандарт гарантирует следующее:
Таким образом аргументы второй функции не могут быть вычислены до аргументов первой, т.к. они разделены двумя точками следования (sequence point).
эквивалентен коду
Т.е. в этом коде разыменование — это вот это:
А взятие адреса там уже после разыменования.
При внесении новых фич не только не заботился об обратной совместимости, но даже считал это достоинством пульса.
Это что за гуру такие? Гуру по прохождениям собеседований? :)