boost :: asio :: sécurité des threads socket

( C'est une version simplifiée de ma question initiale )

J'ai plusieurs threads qui écrivent pour un coup de pouce asio socket. Cela semble fonctionner très bien, pas de problèmes.

La documentation dit un socle commun n'est pas thread-safe( icilà-bas au fond ) donc je me demandais si je devais protéger le support, avec des mutex, ou quelque chose.

Ce question insiste sur le fait que la protection est nécessaire, mais ne donne pas de conseils sur la façon de le faire.

Toutes les réponses à ma question initiale a également insisté pour que ce que je faisais dangereux, et la plupart m'ont poussé à remplacer mon écrit avec async_writes ou encore plus compliqué les choses. Cependant, je suis réticent à le faire, puisque cela ne ferait que compliquer le code qui est déjà au travail et aucun des answerers m'a convaincu qu'ils savaient ce qu'ils ware parlent - ils semblaient avoir lu la documentation que j'ai et ont été deviner, juste comme je l'ai été.

Alors, j'ai écrit un petit programme de test de stress de l'écriture d'un socle commun de deux threads.

Ici, c'est le serveur qui écrit simplement ce qu'elle reçoit du client

int main()
{
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3001));

    tcp::socket socket(io_service);
    acceptor.accept(socket);

    for (;;)
    {
        char mybuffer[1256];
        int len = socket.read_some(boost::asio::buffer(mybuffer,1256));
        mybuffer[len] = '
int main()
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3001));
tcp::socket socket(io_service);
acceptor.accept(socket);
for (;;)
{
char mybuffer[1256];
int len = socket.read_some(boost::asio::buffer(mybuffer,1256));
mybuffer[len] = '\0';
std::cout << mybuffer;
std::cout.flush();
}
return 0;
}
'
; std::cout << mybuffer; std::cout.flush(); } return 0; }

Ici, c'est le client qui crée deux threads écrire sur un socle commun aussi vite qu'ils le peuvent

boost::asio::ip::tcp::socket * psocket;

void speaker1()
{
    string msg("speaker1: hello, server, how are you running?\n");
    for( int k = 0; k < 1000; k++ ) {
        boost::asio::write(
            *psocket,boost::asio::buffer(msg,msg.length()));
    }

}
void speaker2()
{
    string msg("speaker2: hello, server, how are you running?\n");
    for( int k = 0; k < 1000; k++ ) {
        boost::asio::write(
            *psocket,boost::asio::buffer(msg,msg.length()));
    }

}

int main(int argc, char* argv[])
{

    boost::asio::io_service io_service;

  //connect to server

    tcp::resolver resolver(io_service);
    tcp::resolver::query query("localhost", "3001");
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;
    psocket = new tcp::socket(io_service);
    boost::system::error_code error = boost::asio::error::host_not_found;
    while (error && endpoint_iterator != end)
    {
        psocket->close();
        psocket->connect(*endpoint_iterator++, error);
    }


    boost::thread t1( speaker1 );
    boost::thread t2( speaker2 );

    Sleep(50000);

}

Cela fonctionne! Parfaitement, aussi loin que je peux dire. Le client ne se bloque pas. L'arrivée de nouveaux messages sur le serveur sans garbles. Ils arrivent généralement en alternance, un de chaque thread. Parfois un thread obtenir deux ou trois messages avant de les autres, mais je ne pense pas que ce soit un problème, tant qu'il n'y a pas garbles et tous les messages arrivent.

Ma conclusion: la prise ne peut pas être thread-safe dans certains point de vue théorique, mais c'est tellement dur de le faire échouer que je ne vais pas vous en préoccuper.

source d'informationauteur ravenspoint