Сокеты и многопоточность
У меня есть интересная (для меня) проблема... Существует два потока, один для захвата данных из 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 ответа:
Вы держите
nvtMutex
внутри вызоваNVT::recv
. Так как оба потока должны заблокировать мьютекс, чтобы сделать его через итерацию, покаNVT::recv
не возвращает другой поток не может прогрессировать.Не зная подробностей этого класса
NVT
, Невозможно узнать, можно ли безопасно разблокировать мьютекс перед вызовомNVT::recv
или этот класс не обеспечивает должной потокобезопасности, в которой вы нуждаетесь.