首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免在C++11服务器程序中为多个客户端使用多个线程

如何避免在C++11服务器程序中为多个客户端使用多个线程
EN

Stack Overflow用户
提问于 2017-03-03 12:53:15
回答 3查看 571关注 1票数 1

我在一次面试中被问到这个问题,我的回答是避免使用多个线程,使用“协作多任务处理”(单进程)。我非常想知道如何在C++跨平台服务器中有效地处理多个客户机,而不必为每个客户端设置线程。C++11是否提供了一些在这种情况下有用的工具?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-03 13:41:22

通常,您这样做的方式是异步处理请求,即通过回调函数,然后将这些回调函数排队,这样它们就不会冲突。

同步调用与异步调用

同步函数调用和异步函数调用有什么区别?

同步调用:调用一个函数并让它立即完成它的工作。相同的线程执行调用,调用一直阻塞直到函数完成/返回;因此:在它结束之前,什么都不能做。这是您通常在每个正常程序中所做的工作。

异步调用:将函数调用放在队列中,然后可以从同一个或另一个线程调用该函数。

通常,对于客户机/服务器应用程序,您从不使用同步调用来处理传输的数据。一旦你理解了这一点,你就会明白多线程是如何工作的,一切都会变得很简单,

异步调用如何在服务器/客户端程序上工作?

例如,在Boost ASIO中,可以设置要在服务器/客户端接收数据时调用的函数。基本上,您要做的是告诉Boost Library:如果我的服务器接收到数据(比如std::string buffer),我希望您调用这个函数来处理这些数据。

(请注意,同步选择是您调用,并等待直到服务器接收到某件东西,而线程只是完全阻塞直到接收到某件东西。这一点都不方便!这就是为什么同步呼叫不是一个好主意的原因)。

如何从异步编程开始?

Boost ASIO提供了类io_service,它基本上是ASIO异步调用的处理程序。下面是一个例子:

代码语言:javascript
复制
void handle_async_receive(...) { ... }
void print() {
    std::cout<<"Hello!"<<std::endl;
}

int main()
{
    //some stuff
    io_service.post(&print);                             
    socket.connect(endpoint); //this is synchronous, so it connects and returns after the connection process is finished                    
    socket.async_receive(buffer, &handle_async_receive); 
    io_service.post(&print);                             
    io_service.run(); //this will block until the io_service queue is empty
}

当您post时,所有的打印调用都不会发生。您只需将它们放到一个队列中,当您执行run() io_service时,它们将被执行。

多线程呢?

对于多线程,Boost ASIO中有一个名为strand的解决方案。在向io_service发布任何函数之前,您所要做的就是用一条链“包装”它。一个字符串队列函数调用,即使它们位于多个线程上。因此,它是一个非阻塞的解决方案,不像互斥。

票数 3
EN

Stack Overflow用户

发布于 2017-03-03 13:13:22

为了真正避免使用多线程,无论是自己还是通过像Boost.Asio这样的库间接地使用,我将使用轮询/select/epoll(选择您的颜色)监视服务器侦听套接字和所有客户端套接字。默认情况下,您的进程可以处于不超时的状态,等待发生套接字事件。

然后,这取决于您的服务器进程是否完成了所有的工作,那么您可能需要找到一种将大/长处理请求拆分成较小块的方法,以便给其他客户端一个机会/时间间隔。然后构建这些处理块的队列,检查没有等待的套接字,然后再次处理块,直到块队列再次为空。

如果繁重的工作(例如由数据库完成),将请求发送到数据库,检查套接字,检查来自DB服务器的答复等,直到请求被完全处理为止。

票数 3
EN

Stack Overflow用户

发布于 2017-03-03 13:01:29

我最好的建议是不要自己动手,除非你真的想做(也就是为了你的知识或学习)。

有各种各样的库应该完成这个任务,

boost.asio是其中之一。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42579412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档