- 论坛徽章:
- 2
|
来晚了。。。 很早就注意到这个活动。。。 但年关时各种忙。。。 一直在慢慢修改草稿。。。 今天貌似已经从C/C++版块的置顶里去掉了。。。 再不改完就没机会发的样子。。。
于是赶紧地。。。
这确实是一本不可多得的好书。
这本书给我的感觉与《Windows核心编程》的很类似:整体的、系统的认识就靠它了。
并且本书的焦点就是Linux,而不像其他一些书籍的讨论的是一个很宽泛的*nix。 对不知道APUE在说啥的同学(比如我自己)不妨先看看这本。
1、您在Linux/UNIX系统编程行业的经历及经验
接触电脑的契机首先是游戏。。。 然后才是编程。
不过十多年前网络上的各种资料比现在少得多,尤其是中文资料更少,自己英语水平也很差。。。 在没人领进门的情况学习Linux/UNIX下的编程很难诶。。。
实际情况是老师教什么就是什么,于是最开始的编程环境自然是Windows。。。 根本就没想过除了它之外还有没有其他选择。。。
本科的时候终于有人教了。但实际上没学到什么东西。
上得台面的原因可能是:确实有太多“周边的”新事物要学。
比如编辑器。现在都还有印象的事情是进了vi就不知道怎么退出。。。最终是在Windows上打开VS读取与编辑虚拟机里的文件然后在虚拟机里编译并运行。。。
再比如编译器。在这个课程很久之后才弄明白从编写C/C++的源代码到执行直接到底发生了什么。更久之后才知道调试的情况。
没有IDE只有一个“裸”gcc在那时候根本玩不转。。。 调试什么的只能printf。。。
还要顺带学make。。。 只好复制粘贴然后不明所以地改到貌似能正确工作为止。。。
上不得台面的原因可能是:课程老师吸引力不够。。。
而在同一时间Windows那边的课程已经开始玩GUI了。
虽然编程的方式从“进入main后一步两步三步四步望着天执行什么由程序员说了算”变到“进入main后准备好各种事情然后由用户来决定该先执行什么”会让人一开始难以适应。
但这是在学编程而不需要再去熟悉编程的“周边”环境。并且相比之前那种黑框白字的程序来说要“绚”得多了。
于是精力就耗在这边了。 总之就是没入门。。。
有点跑题了,不过我觉得教育资源的缺少 —— 入门门槛高又没老师(或师傅)带领,能留下的是少数,又会导致下一代人的师傅更少 —— 是推广难的一个很大原因。
之后为了避免依赖MSVC的特定行为所以在Windows下也会使用MinGW/MSYS,慢慢地对gcc,gnumake等工具比较熟悉了。
因为毕业论文需要实现一个可以分配可执行内存的库于是终于逮到机会进行Linux下的系统编程了。。。
看过APUE等书后可以编程,但依然感觉不得要领,The Art of Unix Programming更是飘渺虚无。。。
最后在论坛的这个帖子里经由雨过白鹭洲介绍知道了这本书。
因为没有太多机会进行Linux系统编程于是至今都没能仔细通读这本书。
但在使用许多*nix下工具时出于好奇或是想确认这些工具能像预期般工作时都会拿出来翻翻。
比如一些web服务器是否用了epoll,sendfile等系统调用,一些程序是否在完成必要工作后确实丢弃了root权限,setuid/setgid程序是如何工作的,以及capabilities等等。
2、Linux/UNIX系统编程职业生涯的发展探讨
因为自己主要是搞技术方面的,所以对业务方面只是闲聊时听听。
这里说几个自己听到的也比较有趣的: 定制广告机、基于雷达监控的停车场管理系统、无盘启动。
它们都需要对Linux有很深的了解于是我们就无能为力了。。。
其实广告机做过一段时间,感觉很吃力。。。 并且业务方面也停了于是就没继续做下去了。。。
3、对于新入门的Linux/UNIX系统编程人员来说,您有什么话对他们说?
嗯。。。 一句正确的废话:“尽信书不如无书”。而且也不仅仅针对书。所有的文章、言论 —— 无论出自何人何处 —— 都应该用作参考而不是代替自己思考。
对这个帖子也是这样。这只是我自己的一些经验,肯定无法适应于所有情况,甚至可能根本就是错的。
有了这样的免责声明后就可以胡乱瞎说一些与这本书有关的经验。
首先,不加思考地将书里所教授的技术直接应用到编程里是一个很不好的习惯。
特定于这本书的内容可以用Daemon有关的章节作例子。
实现守护进程时肯定需要这些技术。但要抵制住“因为自己了解了这些技术于是就要将它应用到自己所写的程序里”的诱惑。
自己写一些程序用于练手肯定没问题。但要将它应用到生产环境时可以考虑“该程序是否有必要自守护化”? 是否有方法可以将“守护化”作为一个可复用的功能?
其次,进程本身以及进程之间的继承关系本身就是一种很有效的复用手段。
继续以Daemon作为例子。
为每个程序实现守护化的功能肯定是难以编写与调试的。
将这些功能实现为一个程序库并在每个程序里复用这个库虽然可以减轻这两个问题,但是就我自己的经验来看这两种方式实现出的程序对用户来说区别不大,依然是自守护化,依然难以使用与管理。
考虑另一种方式。
将原本打算实现守护化功能的程序当作一个“普通程序”来实现:保持在前台、使用stdout,stderr、Ctrl-C退出等等。这样不但利于实现也利于调试。它们专心实现自己打算提供的独特的功能。
而守护化获得的好处、日志记录、崩溃重启、端口管理等等都可以作为另一个(或一组)独立的程序来实现。而它们专心实现这部分功能。
两者一结合就可以用统一的方式管理许多服务程序的各个方面:启动脚本(不需要sysvinit,upstart,systemd混杂)、重启策略、日志(目的地,rotate)、界面(CLI,GUI,Web)等等。
每个程序自己实现后一类功能不仅仅难以做到极致,而且还会引发其他问题。
upstart需要知道自守护化的程序到底fork了几次。
daemontools与supervisord还需要一些hack来对付自守护化的程序。
这是何苦。。。
类似地,书中还提到了inetd。
提供网络服务并不一定需要使用socket有关的编程技术。可以编写只使用标准输入输出、环境变量、命令行参数的程序 —— 容易编写调试 —— 并配合其他程的序来提供网络服务。
inetd就是这样一种“其他程序”。Ubuntu仓库里提供的5个ident服务有4个都依赖inetd,只有1个是独立实现ident服务。
CGI服务器也是这样一种“其他程序”。
总之,除了“实打实硬碰硬”的编码方式之外可以考虑充实自己的“工具箱”,并针对具体问题选择合适的方式去实现,而不是学会了锤子就将所有问题当作钉子。
在程序里使用直接使用daemon,socket等等是一种直接的、硬的编程方式。
而daemontools,ident,CGI背后隐含的编程思想是另一种间接的、软的编程方式。它有助于产生更简单、容易编写与维护也更稳定可靠的程序。
抵制住“因为了解某种工具就想在程序里使用”的诱惑 —— 包括后一种软的思想也是一种诱惑 —— 并针对具体问题进行分析选择。
以CGI为例。如果目的是为了提供动态网页,当访问数量上升后就会吃不消。这种情况下是不能选它的。而如果只是想避免使用ssh,让一些管理用的脚本可以在浏览器里点击就可以执行,我觉得它就挺适合的。 |
|