Розетки и многопоточность - PullRequest
2 голосов
/ 24 апреля 2010

У меня есть интересная (для меня) проблема ... Есть два потока, один для сбора данных с ввода std и отправки их через сокет на сервер, а другой - для получения данных из блокирующего сокета. Итак, когда нет ответа от сервера, recv () вызывает неопределенно долго, верно? Но вместо того, чтобы блокировать только его вызывающий поток, он блокирует весь процесс! Почему это происходит?

boost::mutex     nvtMutex;
boost::mutex    strMutex;
boost::mutex    quitMutex;
bool        quit = false;

void *processServerOutput(void *arg)
{
    NVT *nvt = (NVT*)arg;
    while(1)
    {
        // Lock the quitMutex before trying to access to quit variable
        quitMutex.lock();
        if(quit)
        {
            quitMutex.unlock();
            pthread_exit(NULL);
        }
        else
            quitMutex.unlock();

        // Receive output from server
        nvtMutex.lock();
        nvt->receive();
        cout << Util::Instance()->iconv("koi8-r", "utf-8", nvt->getOutBuffer());
        nvtMutex.unlock();

        // Delay
        sleep(1);
    }
}

void *processUserInput(void *arg)
{
    NVT *nvt = (NVT*)arg;

    while(1)
    {
        // Get user's input
        //cin.getline(str, 1023);

        sleep(3);
        strcpy(str, "hello");

        // If we type 'quit', exit from thread
        if(strcmp(str, "quit") == 0)
        {
            // Lock quit variable before trying to modify it
            quitMutex.lock();
            quit = true;
            quitMutex.unlock();

            // Exit from thread
            pthread_exit(NULL);
        }

        // Send the input to server
        nvtMutex.lock();
        nvt->writeUserCommand(Util::Instance()->iconv("utf-8", "koi8-r", str));
        nvt->send();
        nvtMutex.unlock();
    }
}

Ответы [ 2 ]

3 голосов
/ 24 апреля 2010

Вы удерживаете nvtMutex внутри вызова на NVT::recv. Так как оба потока должны заблокировать мьютекс, чтобы пройти через итерацию, пока NVT::recv не вернется, другой поток не сможет прогрессировать.

Не зная подробностей этого NVT класса, невозможно узнать, можете ли вы безопасно разблокировать мьютекс перед вызовом NVT::recv или этот класс не обеспечивает необходимую вам безопасность потоков.

1 голос
/ 24 апреля 2010

Если ваш код реализован правильно, recv блокирует только поток, который его вызывает.

Если это не так, покажите пример кода минимальный , который демонстрирует проблему.

...