Насколько потокобезопасным является boost :: asio? - PullRequest
1 голос
/ 09 мая 2020

У меня есть io_context, который запускается несколькими потоками. Я использую розетки и таймеры. Я знаю, что мне нужно обернуть все async_writes цепочкой, чтобы предотвратить одновременную запись в сокет.

Но могут ли два потока одновременно обращаться к сокету для выдачи async_read и async_write одновременно?

А как насчет вызова shutdown () или close (), когда другой поток вызывает async_read? Или cancel () на таймере?

Нужно ли мне в таких случаях защищать сокет / таймер мьютексом или цепью?

1 Ответ

1 голос
/ 09 мая 2020

Часто спрашивают и отвечают:

Thread Safety

В общем, одновременное использование отдельных объектов безопасно, но небезопасно для одновременного использования одного объекта. Однако такие типы, как io_context, обеспечивают более надежную гарантию того, что можно безопасно использовать один объект одновременно.

Итак, да, вам нужно защитить активный доступ к вашим объектам таймера / сокета. Однако наличие асинхронных операций в полете не является проблемой: речь идет о ваших доступах, требующих вашей синхронизации.

Итак,

 asio::post(strand, [&sock] { sock.shutdown();});

всегда безопасно, а когда у вас есть только 1 поток, выполняющий службу, тогда

post(io_context_, [&sock] { sock.shutdown();});

тоже подойдет. Оба будут иметь эффект безопасной отмены любых асинхронных операций, которые все еще выполняются на sock.

См. Также отличное: Зачем мне нужна цепочка на соединение при использовании boost :: asio?

...