我正在尝试创建一个多客户端服务器。我有这个帖子:
void client_thread(int new_socket)
{
int size;
char inbuffer[BUF];
do
{
cout << "Waiting for messages: " << endl;
size = recv(new_socket, inbuffer, BUF, 0);
} while (true);
}
和这个主要程序:
int main()
{
while (true)
{
//waiting for clients
cout << "Waiting for connections..." << endl;
new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen );
//new client connected
if (new_socket > 0)
{
//start thread
thread(client_thread, new_socket).join();
}
}
return 0;
}
当第一个客户端连接时,线程启动,服务器正在等待来自他的消息。但服务器不再等待新客户了。我不知道为什么。是因为线程函数内部有无限do-while
循环吗?如果线程包含无限循环而阻塞整个程序,那么线程的重点是什么?
答案 0 :(得分:6)
主例程阻塞,因为它等待线程完成:join()
。
如果您不想阻止,请不要join()
您的client_thread。
此异常可能来自您的匿名线程对象的破坏。当您离开if()
范围时,此范围内的所有对象都将被销毁。从http://en.cppreference.com/w/cpp/thread/thread/~thread您可以看到,析构函数调用terminate()
。为避免这种情况,您可以致电detach()
。因此,您必须说thread(client_thread, new_socket).join();
而不是thread(client_thread, new_socket).detach();
。
答案 1 :(得分:2)
你应该创建一个线程并保持对它的引用,直到你加入它。在您的代码中,线程对象在创建后立即被释放,因此如果不立即调用join,则会出现错误。
要正确实现这一点,最好的方法是使用运算符new
在堆上分配对象,并将指针存储在某个列表中。当线程完成后,它可能会从列表中删除自己(不要忘记“互斥”它),或者你可以让另一个专用线程这样做:也许你可以让你的主线程在退出之前加入所有其他线程。