Coder Social home page Coder Social logo

libgo's Introduction

libgo

Build Status

libgo - 协程库、并行编程库

libgo是一个使用C++11编写的协作式调度的stackful协程库, 同时也是一个强大易用的并行编程库

目前支持三个平台:

Linux

MacOSX

Windows (Win7、Win8、Win10 x86 and x64 使用VS2013/2015编译) (要切换到windows分支)

使用libgo编写多线程程序,即可以像golang、erlang这些并发语言一样开发迅速且逻辑简洁,又有C++原生的性能优势,鱼和熊掌从此可以兼得。

libgo有以下特点:

  • 1.提供golang一般功能强大协程,基于corontine编写代码,可以以同步的方式编写简单的代码,同时获得异步的性能,

  • 2.支持海量协程, 创建100万个协程只需使用4.5GB物理内存.(真实值, 而不是刻意压缩stack得到的测试值)

  • 3.支持多线程调度协程, 提供高效的负载均衡策略和协程同步机制, 很容易编写高效的多线程程序.

  • 4.调度线程数支持动态伸缩, 不再有调度慢协程导致头部阻塞效应的问题.

  • 5.使用hook技术让链接进程序的同步的第三方库变为异步调用,大大提升其性能。再也不用担心某些DB官方不提供异步driver了,比如hiredis、mysqlclient这种客户端驱动可以直接使用,并且可以得到不输于异步driver的性能。

  • 6.动态链接和全静态链接均支持,便于使用C++11的用户静态链接生成可执行文件并部署至低版本的linux系统上。

  • 7.提供Channel, 协程锁(co_mutex), 协程读写锁(co_rwmutex), 定时器等特性, 帮助用户更加容易地编写程序.

  • 8.支持协程局部变量(CLS), 并且完全覆盖TLS的所有使用场景(详见教程代码sample13_cls.cpp).

  • 从近两年的用户反馈情况看,有很多用户都是已经有了一个异步非阻塞模型的项目(可能是基于epoll、libuv或asio等网络库),然后需要访问MySQL这类没有提供异步Driver的DB. 常规的连接池+线程池的方案在高并发场景下的开销十分昂贵(每个连接对应一个线程才能达到最佳性能, 几千个指令周期的线程上下文切换消耗+过多的活跃线程会导致OS的调度能力急剧下降), 让许多用户难以接受.

  • 鉴于此种情况, 想要使用libgo解决非阻塞模型中阻塞操作的问题,也是完全不必重构现有代码的, 全新的libgo3.0为此场景量身打造了三大利器, 可以无侵入地解决这个问题:运行环境隔离又可以便捷交互的多调度器(详见教程代码sample1_go.cpp),替代传统线程池方案的libgo协程池(详见教程代码sample10_co_pool.cpp),连接池(详见教程代码sample11_connection_pool.cpp)

  • tutorial目录下有很多教程代码,内含详细的使用说明,让用户可以循序渐进的学习libgo库的使用方法。

  • 如果你发现了任何bug、有好的建议、或使用上有不明之处,可以提交到issue,也可以直接联系作者: email: [email protected]

libgo的编译与使用:

  • Vcpkg:

    如果你已经安装了vcpkg,可以直接使用vcpkg安装:

      $ vcpkg install libgo
    
  • Linux:

    1.使用CMake进行编译安装:

      $ mkdir build
      $ cd build
      $ cmake ..
      $ sudo make uninstall
      $ sudo make install
    
    如果希望编译可调试的版本, "cmake .." 命令执行完毕后执行:
    
      $ make debug
      $ sudo make install
    

    2.动态链接glibc: (libgo放到最前面链接)

      g++ -std=c++11 test.cpp -llibgo -ldl [-lother_libs]
    

    3.全静态链接: (libgo放到最前面链接)

      g++ -std=c++11 test.cpp -llibgo -Wl,--whole-archive -lstatic_hook -lc -lpthread -Wl,--no-whole-archive [-lother_libs] -static
    
  • Windows: (目前windows只支持2.x版本,3.0的windows支持还要等一段时间)

    0.切换到windows分支

    1.使用git submodule update --init --recursive下载Hook子模块

    2.使用CMake构建工程文件.

      比如vs2015(x64):
      $ cmake .. -G"Visual Studio 14 2015 Win64"
    
      比如vs2015(x86):
      $ cmake .. -G"Visual Studio 14 2015"
      
      比如vs2013(x64):
      $ cmake .. -G"Visual Studio 12 2013 Win64"
    

    3.使用时需要include目录:libgo

    4.如果想要执行测试代码, 需要依赖boost库. 且在cmake参数中设置BOOST_ROOT:

      	例如:
      	$ cmake .. -G"Visual Studio 14 2015 Win64" -DBOOST_ROOT="e:\\boost_1_61_0"
    

性能

libgo和golang一样实现了一个完整的调度器(用户只需创建协程,无需关心协程的执行、挂起、资源回收),因此有了和golang对比单线程协程调度性能的资格(功能不对等的情况下没资格做性能对比)。

libgo的调度器还实现了worksteal算法的多线程负载均衡调度,因此有了和golang对比多线程协程调度性能的资格。

测试环境:2018款13寸mac笔记本(cpu最低配)
操作系统:Mac OSX
CPU: 2.3 GHz Intel Core i5(4核心 8线程)
测试脚本:$ test/golang/test.sh thread_number

注意事项(WARNING):

协程中尽量不要使用TLS, 或依赖于TLS实现的不可重入的库函数。
如果不可避免地使用, 要注意在协程切换后要停止访问切换前产生的TLS数据。

可能产生协程切换的行为有以下几种:

  • 用户调用co_yield主动让出cpu.
  • 竞争协程锁、channel读写
  • sleep系列的系统调用
  • poll, select, epoll_wait这类等待事件触发的系统调用
  • DNS相关系统调用(gethostbyname系列)
  • 在阻塞式socket上的connect、accept、数据读写操作
  • 在pipe上的数据读写操作

Linux系统上Hook的系统调用列表:

	connect   
	read      
	readv     
	recv      
	recvfrom  
	recvmsg   
	write     
	writev    
	send      
	sendto    
	sendmsg   
	poll      
	__poll
	select    
	accept    
	sleep     
	usleep    
	nanosleep
	gethostbyname                                                               
	gethostbyname2                                                              
	gethostbyname_r                                                             
	gethostbyname2_r                                                            
	gethostbyaddr                                                               
	gethostbyaddr_r

以上系统调用都是可能阻塞的系统调用, 在协程中使用均不再阻塞整个线程, 阻塞等待期间CPU可以切换到其他协程执行.
在原生线程中执行的被HOOK的系统调用, 与原系统调用的行为保持100%一致, 不会有任何改变.

	socket
	socketpair
	pipe
	pipe2
	close     
	__close
	fcntl     
	ioctl     
	getsockopt
	setsockopt
	dup       
	dup2      
	dup3      

以上系统调用不会造成阻塞, 虽然也被Hook, 但并不会完全改变其行为, 仅用于跟踪socket的选项和状态. 

Windows系统上Hook的系统调用列表:

	ioctlsocket                                                                        
	WSAIoctl                                                                           
	select                                                                             
	connect                                                                            
	WSAConnect                                                                         
	accept                                                                             
	WSAAccept                                                                          
	WSARecv                                                                            
	recv                                                                               
	recvfrom                                                                           
	WSARecvFrom                                                                        
	WSARecvMsg                                                                         
	WSASend                                                                            
	send                                                                               
	sendto                                                                             
	WSASendTo                                                                          
	WSASendMsg

libgo's People

Contributors

higithubhi avatar hungmingwu avatar krysme avatar mlkt avatar sarrow104 avatar soolo-ss avatar xbased avatar xgdgsc avatar yyzybb537 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.