套接字和多线程
我有一个有趣的(对我来说)问题...有两个线程,一个用于从 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();
}
}
I have an interesting (to me) problem... There are two threads, one for capturing data from std input and sending it through socket to server, and another one which receives data from blocking socket. So, when there's no reply from server, recv() call waits indefenitely, right? But instead of blocking only its calling thread, it blocks the overall process! Why this thing occurs?
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将
nvtMutex
保存在对NVT::recv
的调用中。由于两个线程都需要锁定互斥体才能完成迭代,因此在NVT::recv
返回之前,另一个线程无法继续进行。如果不知道此
NVT
类的详细信息,就不可能知道在调用NVT::recv
之前是否可以安全地解锁互斥锁,或者该类是否未提供正确的线程您需要的安全。You are holding the
nvtMutex
inside the call toNVT::recv
. Since both threads need to lock the mutex to make it through an iteration, untilNVT::recv
returns the other thread can't progress.Without knowing the details of this
NVT
class, it's impossible to know if you can safely unlock the mutex before callingNVT::recv
or if this class does not provide the proper thread safety you need.如果您的代码实现正确,
recv
只会阻塞调用它的线程。如果您的情况并非如此,请显示演示该问题的最小代码示例。
If your code is implemented correctly,
recv
blocks only the thread that invokes it.If this isn't the case for you, show the minimal code sample that demonstrates the problem.