Конечно не Coroutines TS — их я критикую в своем комменте.
А эти я привел как пример того, что можно все сделать проще, если стоит задача асинхронный код сделать «синхронным» по форме.
A race condition or race hazard is the behavior of an electronic or software system where the output is dependent on the sequence or timing of other uncontrollable events.
Т.е. буквально то что происходит при копировании в один буфер из нескольких потоков.
Нет. Наоборот.
Мой пример доказывает, что потокобезопасность по POSIX не гарантирует отсутствие race condition.
А именно race condition и является причиной наблюдаемого поведения.
У вас есть возражения против того что оба эти условия выполняются?
1) memcpy потокобезопасна по POSIX
2) memcpy не потокобезопасна при передаче одного и того же буфера из разных потоков
Вызов из двух потоков некорректен.
А мьютекс там нужен, чтобы ядро могло защититься от дураков и сохранить внутренние структуры в консистентном состоянии.
Совсем не обязательно что после такой защиты вы получите хоть какой-то полезный или повторяемый результат.
Вы неверно понимаете что имеется в виду под thread-safe в POSIX.
Например memcpy потокобезопасна с точки зрения POSIX.
То есть ее ВООБЩЕ можно вызывать из нескольких потоков одновременно.
Однако вызов из двух потоков с одним и тем же приемным буфером не является потокобезопасным.
Точно по той же причине, одновременный вызов read для одного и того же дескриптора из разных потоков тоже не является безопасным, хотя read сама по себе потокобезопасна.
Как выше написал encyclopedist:
1) If CLONE_FILES is set, the calling process and the child process share the same file descriptor table
2) в glibc в функции create_thread используестся такой набор флагов ...CLONE_FILES…
Мы уже показали что при вызове join() состояния сокетов синхронизируются.
Все что мой код выше показывает — это то что если сокеты применять потокобезопасно (как и следует), то никаких таких «эффектов», которые вы себе придумали — нет.
А когда нет потокобезопасности (как в вашем первом примере) — это обычный undefined behaviour. Утверждать что либо для такого кода бессмысленно.
github.com/vapourismo/luwra
Обертка класса выглядит даже проще чем обертки для ChaiScript
version
event
Тут применяется возможность передать имя макроса в качестве параметра в другой макрос.
Такой стиль поддерживают более менее все.
А эти я привел как пример того, что можно все сделать проще, если стоит задача асинхронный код сделать «синхронным» по форме.
В Asio можно намного проще корутины использовать. Неявно.
Т.е. буквально то что происходит при копировании в один буфер из нескольких потоков.
Мой пример доказывает, что потокобезопасность по POSIX не гарантирует отсутствие race condition.
А именно race condition и является причиной наблюдаемого поведения.
1) memcpy потокобезопасна по POSIX
2) memcpy не потокобезопасна при передаче одного и того же буфера из разных потоков
Поэтому привел простой и понятный пример (memcpy) подтверждающий мои слова.
А мьютекс там нужен, чтобы ядро могло защититься от дураков и сохранить внутренние структуры в консистентном состоянии.
Совсем не обязательно что после такой защиты вы получите хоть какой-то полезный или повторяемый результат.
Например memcpy потокобезопасна с точки зрения POSIX.
То есть ее ВООБЩЕ можно вызывать из нескольких потоков одновременно.
Однако вызов из двух потоков с одним и тем же приемным буфером не является потокобезопасным.
Точно по той же причине, одновременный вызов read для одного и того же дескриптора из разных потоков тоже не является безопасным, хотя read сама по себе потокобезопасна.
А вообще, да, расскажите, что происходит, если из обработчика сигнала вызвать read, а данных еще нет :)
Как выше написал encyclopedist:
1) If CLONE_FILES is set, the calling process and the child process share the same file descriptor table
2) в glibc в функции create_thread используестся такой набор флагов ...CLONE_FILES…
Т.е. ничего не клонируется.
Вопрос закрыт.
Все что мой код выше показывает — это то что если сокеты применять потокобезопасно (как и следует), то никаких таких «эффектов», которые вы себе придумали — нет.
А когда нет потокобезопасности (как в вашем первом примере) — это обычный undefined behaviour. Утверждать что либо для такого кода бессмысленно.