170 похожих чатов

Добрый день! Подскажите, пожалуйста, по потокобезопасности отдельных частей Boost.ASIO/ASIO. Дано: 1) Приложение, использующее,

допустим 8 потоков.
2) Контекст asio::io_context my_context.
3) Сокет asio::ip::tcp::socket my_sock(my_context).

На первой половине потоков [0-3] выполняется run() у общего my_context.
На второй половине потоков [4-7] выполняется другой код.

Подскажите, пожалуста, насколько безопасно вызывать метод my_sock.close(ec) в следующих случаях:
1) Из кода, который выполняется внутри my_context (потоки [0-3])?
2) Из кода, который выполняется на других потоках [4-7]?

В обоих случаях гарантируется, что переменная my_sock валидна, деструктор у нее не вызывается, метод close() будет вызывать только один поток без конкуренции, но в сокете my_sock в это время может быть любая активность по сети и коллбекам.


И есть аналогичный вопрос для таймеров basic_waitable_timer, только вместо close вызываться будет cancel.


Документацию я читаю, и этот момент с гарантиями понять не могу...
Где-то я туплю, но вот где именно... 🙁

7 ответов

29 просмотров

А вот откуда поток который хочет сказать close знает о сокете для начала?

Vladislav-Shchapov Автор вопроса
Dmitry Sokolov
А вот откуда поток который хочет сказать close зна...

Например, коллбек таймера таймаута «кранты» вызвался в другом потоке. А раз сработал таймер уровня «кранты», то единственная имеющая смысл операция для сокета - закрыть/оборвать сокет. Вопрос - как это сделать безопасно. Вероятность того, что на той стороне кто-то еще ждет, мала так что EOF от shutdown может не дойти и с точки зрения самих сокетов я бы в этом случае вызывал именно close(). (на случай, если вдруг что-то еще с той стороны прилетит, чтобы порт сразу не переиспользовался).

Vladislav Shchapov
Например, коллбек таймера таймаута «кранты» вызвал...

Есть наверное какой-то враппер, типа сессии. Сам то хэндл можно закрыть откуда угодно (и при этом всякие read/write прервутся). Но тут опасно то что останется сессия и её read/write cb с невалидным хэндлом. Это опасно, он может быть уже переиспользован. Надо на сессии все операции (включая таймеры) пускать через strand.

Vladislav-Shchapov Автор вопроса
Dmitry Sokolov
Есть наверное какой-то враппер, типа сессии. Сам т...

Невалидность сокета в любом случае не важна, так как асинхронные операции завершатся по asio::error::operation_aborted - это документировано. А дальше их не перезапускать - это уже ответственность кода сессии (она то знает, что случился таймаут кранты). Деструктор сокета в моем случе тоже не вызовается параллельно в close. strand - это хорошо, но это лишние мьютексты на пути, где всео перации кроме cancel таймера - последовательны.

Vladislav Shchapov
Невалидность сокета в любом случае не важна, так к...

Strand это не то чтобы мьютексы... Это очередь внутри очереди.

Vladislav Shchapov
Невалидность сокета в любом случае не важна, так к...

Нет, всё равно strand нужен. Вы больше получите неприятностей при параллельно выполняющихся dradline/read callback.

Vladislav-Shchapov Автор вопроса
Dmitry Sokolov
Strand это не то чтобы мьютексы... Это очередь вну...

Которая не локфри, а защищается мьютексами.

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта