Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 服务器多线程,协议必须的吗?还有更多_C_Architecture_Networking_Protocol Buffers - Fatal编程技术网

C 服务器多线程,协议必须的吗?还有更多

C 服务器多线程,协议必须的吗?还有更多,c,architecture,networking,protocol-buffers,C,Architecture,Networking,Protocol Buffers,假设应用程序级协议是通过UDP实现的。客户机超时是必需的,所以服务器需要保持它与之对话的每个客户机的状态 还假设使用了select 实现多线程服务器总是最好的吗?我想链接列表也会这样做,其中服务器超时时间=客户端的最早超时-CurrentTime。链接列表将具有与保持客户机状态相同的功能,同时避免创建新线程的开销(尽管为服务器维护特定于客户机的超时引入了一些复杂性) 如果选择了多线程,那么接下来,是否最好为新客户机调用新套接字?这将引入系统资源开销。但是我认为默认的服务器套接字(bindwith

假设应用程序级协议是通过UDP实现的。客户机超时是必需的,所以服务器需要保持它与之对话的每个客户机的状态

还假设使用了
select

  • 实现多线程服务器总是最好的吗?我想链接列表也会这样做,其中服务器超时<代码>时间=客户端的最早超时-CurrentTime。链接列表将具有与保持客户机状态相同的功能,同时避免创建新线程的开销(尽管为服务器维护特定于客户机的超时引入了一些复杂性)

  • 如果选择了多线程,那么接下来,是否最好为新客户机调用新套接字?这将引入系统资源开销。但是我认为默认的服务器套接字(
    bind
    withserver-well-known-port)也会这样做,因为它有缓冲区(嗯..可能不够长,无法容纳可伸缩的客户端数量..)


  • 谢谢

    多线程绝对不是必须的,因为您已经找到了替代方案。我们不能像总是或从不那样使用绝对值,因为每种情况都有独特的要求和约束

    是的,为每个连接添加新线程/套接字将消耗更多资源。听起来你需要很好地定义你需要多少连接。然后你可以决定你是否有足够的资源


    如果不考虑资源限制,我会选择更简单的解决方案。与编写新的功能体(链表建议)相比,使用您已有的工具(即处理线程和套接字的经过良好测试的函数)是否更容易?代码维护呢?如果将来有另一个程序员在这个项目上工作,他们会更容易理解使用他们已经熟悉的标准操作系统调用的实现,还是使用链表?

    链表将无法扩展

    使用服务器端的链表逐个检查客户机并满足他们的需求对于5到10个客户机来说都很好。但是当你有100个时会发生什么呢?1000? 如果一个客户端的请求需要很长时间才能处理,会发生什么情况

    线程不仅仅为单个客户端提供了一种维护状态的方法。它们还提供了一种跨所有客户端同时“分配服务器资源”的方法。就好像每个客户机都有一个专用的服务器,几乎没有队列:客户机想要什么,它询问服务器,服务器回复。这是瞬间的


    此外,使用链表方法可能会浪费宝贵的资源。如果除了一个客户之外所有客户都不想要什么呢?您将在上百个客户端上重复循环,除了浪费CPU周期外,什么也不做,直到遇到需要服务器注意的客户端。

    根据我的经验,线程化使您的代码在潜伏着可怕的同步问题时很容易看起来逻辑清晰,等待某些事件以应用程序启动的正确顺序发生。线程是一个非常有用的工具-如果你的应用程序要充分利用你的CPU,你需要考虑线程,学习使用线程是学习利用分布式处理的一个步骤(至少,我认为是这样)

    我的首选是使用异步回调编写应用程序,而不是阻塞调用,并显式指示要使用哪个线程来处理回调。这有以下优点:

    • 它使状态变量交互更加可控,因此可以预测,这意味着线程更健壮。
    • 如果操作正确,它可以充分利用CPU拥有的处理器数量。
    • 它允许您直接控制要赋予某些函数的优先级-如果此函数为高优先级,则将其分派给高优先级线程,然后在完成时,通过调用方线程中的延续将结果发送回低优先级调用方。或者到另一个线程-没有理由限制它。
    • 通常可以移植到非线程环境。也许对大多数人来说并不重要,但有时对我来说很重要。

    我不打算提出艾丹·卡利答案中没有的任何新建议,但是,请看一看Apache多处理模块背后的理论:


    本质上,服务器被分为多个模块,创建线程/进程来管理连接,这取决于需要和配置选项——这听起来像是Aidan回答中描述的平衡,尽管Apache实现可能略有不同。

    是的,我在Apache(httpd)中有些活跃当它的处理模型被引入时,社区和围绕它的讨论与我的想法有很大关系。aaaaah当时是这方面的专家-这似乎是一个非常明智的方法,我打算继续一个后续项目,我正在做@work。谢谢你的解释,特别是维修部分,谢谢你的建议。我想我会遵循常规模式。但是,与dua内核相比,线程在单核系统上并没有多大用处。@Computer Guru-相对于轮询体系结构来说,这是正确的,但我认为相对于设计良好的基于AIO(或其他基于中断的)体系结构来说,它不会是正确的。在单核上,线程基本上简化为基于中断的体系结构。这是一个相当笼统的说法。我已经看到EFNet服务器愉快地处理了15000多个并发客户端——使用单线程的
    ircd
    ,基本上就是所描述的方法。因此,它很可能具有足够的可扩展性。