linux高性能服务器开发十大必须掌握的核心技术( 二 )


【文章福利】需要C/C++ Linux服务器架构师学习资料加群812855908(资料包括C/C++,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等)

linux高性能服务器开发十大必须掌握的核心技术

文章插图
 
有没有一些轻量级的方案来实现多线程安全的访问数据呢?这个时候,你需要:
无锁编程技术多线程并发编程中,遇到公共数据时就需要进行线程同步 。而这里的同步又可以分为阻塞型同步和非阻塞型同步 。
阻塞型同步好理解,我们常用的互斥体、信号、条件变量等这些操作系统提供的机制都属于阻塞型同步,其本质都是要加“锁” 。
linux高性能服务器开发十大必须掌握的核心技术

文章插图
 
与之对应的非阻塞型同步就是在无锁的情况下实现同步,目前有三类技术方案:
  • Wait-free
  • Lock-free
  • Obstruction-free
 
三类技术方案都是通过一定的算法和技术手段来实现不用阻塞等待而实现同步,这其中又以Lock-free最为应用广泛 。
Lock-free能够广泛应用得益于目前主流的CPU都提供了原子级别的read-modify-write原语,这就是著名的CAS(Compare-And-Swap)操作 。在Intel x86系列处理器上,就是cmpxchg系列指令 。
// 通过CAS操作实现Lock-freedo {...} while(!CAS(ptr,old_data,new_data ))我们常常见到的无锁队列、无锁链表、无锁HashMap等数据结构,其无锁的核心大都来源于此 。在日常开发中,恰当的运用无锁化编程技术,可以有效地降低多线程阻塞和切换带来的额外开销,提升性能 。
服务器上线了一段时间,发现服务经常崩溃异常,排查发现是工作线程代码bug,一崩溃整个服务都不可用了 。于是你决定把工作线程和主线程拆开到不同的进程中,工作线程崩溃不能影响整体的服务 。这个时候出现了多进程,你需要:
进程间通信技术提起进程间通信,你能想到的是什么?
  • 管道
  • 命名管道
  • socket
  • 消息队列
  • 信号
  • 信号量
  • 共享内存
以上各种进程间通信的方式详细介绍和比较,推荐一篇文章浅析进程间通信的几种方式(含实例源码),这里不再赘述 。
对于本地进程间需要高频次的大量数据交互,首推共享内存这种方案 。
现代操作系统普遍采用了基于虚拟内存的管理方案,在这种内存管理方式之下,各个进程之间进行了强制隔离 。程序代码中使用的内存地址均是一个虚拟地址,由操作系统的内存管理算法提前分配映射到对应的物理内存页面,CPU在执行代码指令时,对访问到的内存地址再进行实时的转换翻译 。
linux高性能服务器开发十大必须掌握的核心技术

文章插图
 
从上图可以看出,不同进程之中,虽然是同一个内存地址,最终在操作系统和CPU的配合下,实际存储数据的内存页面却是不同的 。
而共享内存这种进程间通信方案的核心在于:


推荐阅读