boost:: asio:: socket thread safety

(Это упрощенная версия моего первоначального вопроса)

У меня есть несколько потоков, которые записывают в сокет boost asio. Кажется, это работает очень хорошо, без проблем.

В документации говорится, что общий разъем не защищен от потоков ( здесь , путь внизу), поэтому мне интересно, должен ли я защитить разъем с помощью мьютекса или чего-то еще.

Этот вопрос настаивает на том, что защита необходима, но не дает никаких советов относительно того, как это сделать.

Все ответы на мой первоначальный вопрос также настаивали на том, что то, что я делаю, опасно, и большинство призывали меня заменить свои записи async_writes или даже более сложными вещами. Однако я неохотно это делаю, так как это усложнит уже работающий код и никто из ответчиков не убедил меня, что они знают, о чем говорят, - они, казалось, прочитали ту же документацию, что и я, и догадывались, точно так же, как и я.

Итак, я написал простую программу для стресс-теста записи в общий сокет из двух потоков.

Вот сервер, который просто записывает все, что получает от клиента

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;
}

Вот клиент, который создает два потока, которые записывают в общий сокет так быстро, как они могут

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);

}

Это работает! Отлично, насколько я могу судить. Клиент не выполняет сбой. Сообщения поступают на сервер без искажений. Обычно они прибывают поочередно, по одному из каждой нити. Иногда одна нить получает два или три сообщения перед другой, но я не думаю, что это проблема, пока нет никаких шалостей и все сообщения приходят.

Мой вывод: розетка может быть небезопасна в каком-то теоретическом смысле, но трудно сделать так, чтобы она провалилась, что я не буду беспокоиться об этом.

-121--941447-

Поведение «выхода» Python Я читаю о ключевом слове выхода в python, и пытаюсь понять выполнение этого образца: def countfrom (n): в то время как True: print «before выход» выход n n + = 1...

Я читаю о ключевом слове выхода в python и пытаюсь понять выполнение этого образца:

def countfrom(n):
    while True:
        print "before yield"
        yield n
        n += 1
        print "after yield"

for i in countfrom(10):
    print "enter for loop"
    if i <= 20:
        print i
    else:
        break

Вывод:

before yield
enter for loop
10
after yield
before yield
enter for loop
11
after yield
before yield
enter for loop
12
after yield
before yield
enter for loop
13
after yield
before yield
enter for loop
14
after yield
before yield
enter for loop
15
after yield
before yield
enter for loop
16
after yield
before yield
enter for loop
17
after yield
before yield
enter for loop
18
after yield
before yield
enter for loop
19
after yield
before yield
enter for loop
20
after yield
before yield
enter for loop

Похоже, что выход вернет указанное значение и продолжит выполнение функции до конца (в параллельном потоке, может быть). Правильно ли мое понимание?

Если бы вы могли ответить на это, не упомянув «генераторы», я был бы благодарен, потому что я пытаюсь понять по одному.

10
задан David Heffernan 9 September 2011 в 14:11
поделиться