zoukankan      html  css  js  c++  java
  • 高性能服务器开发之线程结构

    线程结构相当于服务器程序的灵魂,一个好的服务器程序必须线程结构清析且线程利用率高。下面主要以伪代码的形式列举一些常用的线程结构。

    1 单业务处理线程结构

    int main()
    {
    	Init();
    
    	while (queue.GetMessage(timeout, message)) // 这里的队列要支持多个线程写,一个线程读
    	{
    		DispatchMessage(message);
    		DetectTimer(); // 如果需要定时器的话
    	}
    
    	DeInit();
    
    	return 0;
    }
    

    windows窗口程序及我见过的大部分网游服务器都使用这种线程结构。因为只有一个业务处理主线程,在进行业务处理的时候,不需要考虑线程同步。当然这种服务器并不只是只有一个线程在工作,通常网络和DB(如果有的话)会使用独立的线程,例如当网络收到一个消息后,就Enqueue到队列中,这时queue.GetMessage返回,由DispatchMessage找到对应的处理函数去做具体的处理。

    2 多业务处理线程

    int main()
    {
    	Init();
    
    	for (1 to 10)
    	{
    		StartThread(&ThreadFunction);
    	}
    
    	WaitForExit();
    	DeInit();
    
    	return 0;
    }
    
    int ThreadFunction()
    {
    	while (queue.GetMessage(timeout, message)) // 队列要支持多写多读
    	{
    		DispatchMessage(message);
    	}
    	return 0;
    }
    

    网络线程收到消息后,Enqueue到队列,其中一个线程的GetMessage会返回并处理。DB模块通常使用这种线程结构。

    3 并发单线程

    class WorkThread
    {
    public:
    	void Start();
    
    private:
    	void AsnycRead(int clientId);
    	void AsnycWrite(int clientId, Message* message);
    
    	void OnRead(int clientId, Message* message);
    	void OnWriteComplite(int clientId);
    };
    
    int main()
    {
    	for (1 to 10)
    	{
    		new WorkThread();
    	}
    
    	WaitForExit();
    
    	return 0;
    }
    

    我其实没找到一个好的名称和伪代码去描述这种线程结构,多加点文字说明吧。这种线程结构通常在程序启动时开启多个线程(通常是CPU核芯数),每个线程完整的加载其需要的配置,每个线程都是独立的且功能都是一样的,线程与线程之间没有仍何交互,用户代码中没有队列。一个连接建立好后,始终在同一个线程空间中运行,因此也没有任何线程同步。这种线程序结构非常适合网关类、转发类等慢操作比较少的服务器,能充分利用多核的CPU资源,提高服务效率。使用iocp及boost.asio很容易实现这种线程结构。

    4 线程池

    int main()
    {
    	Init();
    
    	for (1 to 100)
    	{
    		ThreadPool.Add(new WorkThread());
    	}
    
    	WaitTask();
    
    	WaitForExit();
    	DeInit();
    
    	return 0;
    }
    
    void WaitTask()
    {
    	WorkThread t = ThreadPool.GetFree();
    	t.Wakeup(); // 唤醒子线程后立即返回,子线程等待客户端连接,连接成功后先Wakeup下一个线程去等待客户端连接, 由本线程执行任务
    }
    

    曾经比较火的Leader/Follower模式,据说tomcat用的就是这个,但个人觉得这种结构效率并不高,因为这种模式网络IO通常用同步,大大降低了线程的利用率。

    结束语

    以上只上对线程结构的简化描述,实际用到的服务器并不会只这么简单,可能是多种结构的组合,也可能是上面没提到的线程结构。但高并发高效率的服务器要点其实很简单:提高每个线程的利用率,尽量避免忙等、睡眠及过多的线程切换,同时减少加锁及各种队列的入列出列。业务处理方面可将业务细化,由单服务器处理转成多服务器处理,能并发的就并发……不过这超出了本文的范围,有机会再详述。

    附感言

    在08年之前,boost还不是那么流行,我通常会使用自己实现的线程相关的基础库,如Mutex, Condition, Thread, SharedPtr, MessageQueue——当然基本上也是从boost中抄过来的。时间飞奔,2016年的现在,C11也包含了以上大部分库,还剩MessageQueue实现起来也是分分钟的事……时代更美好了!

  • 相关阅读:
    获取全部校园新闻
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    编写可维护的JavaScript
    markDown使用
    好文推荐系列---------JS模板引擎
    backbone框架思路
    如何获取URL中的参数
    如何使用NodeJs来监听文件变化
    sass基本用法(转载)
  • 原文地址:https://www.cnblogs.com/junye/p/5831708.html
Copyright © 2011-2022 走看看