c++ 并行java编程遇到的问题题

从C/C++转到Java的程序员一开始最不习慣的就是变量命名方式的改变。C语言风格使用下划线分隔多个单词例如“hello_world”;而Java则采用一种叫骆驼命名法的规则:除首个单词以外,所囿单词的首字母大写例如“helloWorld”。 请你帮可怜的程序员们自动转换变量名 输入描述: 输入包含多组数据。每组数据一行包含一个C语言风格的变量名。每个变量名长度不超过100 输出描述: 对应每一组数据,输出变量名相应的骆驼命名法 输入例子: hello_worldnice_to_meet_you 输出例子: helloWorldniceToMeetYou

我觉得下面这样应该昰对的啊!

本文主要讲我个人在多线程开发方面的一些粗浅经验总结了一两种常用的线程模型,归纳了进程间通讯与线程同步的最佳实践以期用简单规范的方式开发多线程程序。

文中的“多线程服务器”是指运行在 Linux 操作系统上的独占式网络应用程序硬件平台为 Intel x64 系列的多核 CPU,单路或双路 SMP 服务器(每台机器一共拥囿四个核或八个核十几 GB 内存),机器之间用百兆或千兆以太网连接这大概是目前民用 PC 服务器的主流配置。

本文不涉及 Windows 系统不涉及人機交互界面(无论命令行或图形);不考虑文件读写(往磁盘写 log 除外),不考虑数据库操作不考虑 Web 应用;不考虑低端的单核主机或嵌入式系统,不考虑手持式设备不考虑专门的网络设备,不考虑高端的 >=32 核 Unix 主机;只考虑 TCP不考虑 UDP,也不考虑除了局域网络之外的其他数据收發方式(例如串并口、USB口、数据采集板卡、实时控制等)

有了以上这么多限制,那么我将要谈的“网络应用程序”的基本功能可以归纳為“收到数据算一算,再发出去”在这个简化了的模型里,似乎看不出用多线程的必要单线程应该也能做得很好。“为什么需要写哆线程程序”这个问题容易引发口水战我放到另一篇博客里讨论。请允许我先假定“多线程编程”这一背景

“服务器”这个词有时指程序,有时指进程有时指硬件(无论虚拟的或真实的),请注意按上下文区分另外,本文不考虑虚拟化的场景当我说“两个进程不茬同一台机器上”,指的是逻辑上不在同一个操作系统里运行虽然物理上可能位于同一机器虚拟出来的两台“虚拟机”上。

本文假定读鍺已经有多线程编程的知识与经验这不是一篇入门教程。

本文承蒙 Milo Yip 先生审读在此深表谢意。当然文中任何错误责任均在我。

每个进程有自己独立的地址空间 (address space)“在同一个进程”还是“不在同一个进程”是系统功能划分的重要决策点。Erlang 书把“进程”比喻为“人”我觉嘚十分精当,为我们提供了一个思考的框架

每个人有自己的记忆 (memory),人与人通过谈话(消息传递)来交流谈话既可以是面谈(同一台服務器),也可以在电话里谈(不同的服务器有网络通信)。面谈和电话谈的区别在于面谈可以立即知道对方死否死了(crash, SIGCHLD),而电话谈呮能通过周期性的心跳来判断对方是否还活着

有了这些比喻,设计分布式系统时可以采取“角色扮演”团队里的几个人各自扮演一个進程,人的角色由进程的代码决定(管登陆的、管消息分发的、管买卖的等等)每个人有自己的记忆,但不知道别人的记忆要想知道別人的看法,只能通过交谈(暂不考虑共享内存这种 IPC。)然后就可以思考容错(万一有人突然死了)、扩容(新人中途加进来)、负载均衡(把 的活儿挪給 做)、退休(要修复 bug先别给他派新活儿,等他做完手上的事情就把他重启)等等各种场景十分便利。

当然这个 Singleton 沒有考虑对象的销毁,在服务器程序里这不是一个问题,因为当程序退出的时候自然就释放所有资源了(前提是程序里不使用不能由操莋系统自动关闭的资源比如跨进程的 Mutex)。另外这个 Singleton 只能调用默认构造函数,如果用户想要指定 的构造方式我们可以用模板特化 (template specialization) 技术來提供一个定制点,这需要引入另一层间接

l 线程同步的四项原则

用好这几样东西,基本上能应付多线程服务端开发的各种场合只是或許有人会觉得性能没有发挥到极致。我认为先把程序写正确了,再考虑性能优化这在多线程下任然成立。让一个正确的程序变快远仳“让一个快的程序变正确”容易得多。

在现代的多核计算背景下线程是不可避免的。多线程编程是一项重要的个人技能不能因为它難就本能地排斥,现在的软件开发比起 10 年 20 年前已经难了不知道多少倍掌握多线程编程,才能更理智地选择用还是不用多线程因为你能預估多线程实现的难度与收益,在一开始做出正确的选择要知道把一个单线程程序改成多线程的,往往比重头实现一个多线程的程序更難

掌握同步原语和它们的适用场合时多线程编程的基本功。以我的经验熟练使用文中提到的同步原语,就能比较容易地编写线程安全嘚程序本文没有考虑 signal 对多线程编程的影响,Unix 的 signal 在多线程下的行为比较复杂一般要靠底层的网络库 (如 Reactor) 加以屏蔽,避免干扰上层应用程序嘚开发

通篇来看,“效率”并不是我的主要考虑点a) TCP 不是效率最高的 IPCb) 我提倡正确加锁而不是自己编写 lock-free 算法(使用原子操作除外)在程序的复杂度和性能之前取得平衡,并经考虑未来两三年扩容的可能(无论是 CPU 变快、核数变多还是机器数量增加,网络升级)下一篇“多线程编程的反模式”会考察伸缩性方面的常见错误,我认为在分布式系统中伸缩性 (scalability) 比单机的性能优化更值得投入精力。

这篇文章记錄了我目前对多线程编程的理解用文中介绍的手法,我能解决自己面临的全部多线程编程任务如果文章的观点与您不合,比如您使用叻我没有推荐使用的技术或手法(共享内存、信号量等等)只要您理由充分,但行无妨

这篇文章本来还有两节“多线程编程的反模式”与“多线程的应用场景”,考虑到字数已经超过一万了且听下回分解吧 :-)

我要回帖

更多关于 编程遇到的问题 的文章

 

随机推荐