记录学习过程中的点点滴滴
2010年十二月
CentOS配置NFS服务器的方法
十二 31st
最近搞KVM虚拟机迁移,前提是需要一个共享存储的文件系统来存储系统镜像,本来打算使用KFS来作为分布式文件系统的,但是在修改kvm的镜像读写API后,系统是跑起来了,但是奇慢无比,主要是存在对镜像存在大量的随机读写造成的,这个下次再好好总结下。所以就想到了简单易用的NFS文件系统,下面是具体的配置细节:
1,NFS服务器的安装
在CentOS系统中,默认情况下已经安装了NFS文件系统,如果没有安装就需要手工安装了
#rpm –q nfs-utils portmap
2, 查看NFS是否启动
#service nfs starus #service portmap status
3,启动NFS
#service nfs start #service portmap status
更多 >
C语言调用C++库接口的方法概述
十二 28th
最近需要在由纯c语言编写的代码中调用C++的动态库,在网上找了一些资料,现在总结下解决方法。
主要的思想就是将C++的动态库再封装一层,在这一层编写C语言的函数api,这API中使用C++动态库提供的类;
具体例子如下:
1,假如C++动态库包含如下代码:
//myclass.h
#ifndef _MYCLASS_H #define _MYCLASS_H class MyClass { public: void print(); }; #endif
//myclass.cc
#include <iostream> #include "myclass.h" using namespace std; void MyClass::print() { cout < < "MyClass::print() called" << endl; }
编译链接生成动态库:libmyclass.so
g++ myclass.cc -shared -o libmyclass.so -I./ -fPIC
更多 >
使用事件驱动模型实现高效稳定的网络服务器程序【写得比较基础详细】
十二 23rd
前言
事件驱动为广大的程序员所熟悉,其最为人津津乐道的是在图形化界面编程中的应用;事实上,在网络编程中事件驱动也被广泛使用,并大规模部署在 高连接数高吞吐量的服务器程序中,如 http 服务器程序、ftp 服务器程序等。相比于传统的网络编程方式,事件驱动能够极大的降低资源占用,增大服务接待能力,并提高网络传输效率。
关于本文提及的服务器模型,搜索网络可以查阅到很多的实现代码,所以,本文将不拘泥于源代码的陈列与分析,而侧重模型的介绍和比较。使用 libev 事件驱动库的服务器模型将给出实现代码。
阻塞型的网络编程接口
几乎所有的程序员第一次接触到的网络编程都是从 listen()、send()、recv() 等接口开始的。使用这些接口可以很方便的构建服务器 / 客户机的模型。
我们假设希望建立一个简单的服务器程序,实现向单个客户机提供类似于“一问一答”的内容服务。
图 1. 简单的一问一答的服务器 / 客户机模型
我们注意到,大部分的 socket 接口都是阻塞型的。所谓阻塞型接口是指系统调用(一般是 IO 接口)不返回调用结果并让当前线程一直阻塞,只有当该系统调用获得结果或者超时出错时才返回。
实际上,除非特别指定,几乎所有的 IO 接口 ( 包括 socket 接口 ) 都是阻塞型的。这给网络编程带来了一个很大的问题,如在调用 send() 的同时,线程将被阻塞,在此期间,线程将无法执行任何运算或响应任何的网络请求。这给多客户机、多业务逻辑的网络编程带来了挑战。这时,很多程序员可能会 选择多线程的方式来解决这个问题。
更多 >
WPO[Web 性能优化与运维]会议链接
十二 12th
linux中container_of用法详解
十二 11th
今天看内核代码,发现container_of的用法,上网查下它的用法,原来是 在已知结构体的某个成员的指针时,求出整个结构体的首指针地址,具体宏展开如下:
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
具体解释如下:
typeof是gcc的一个扩展,用于确定一个变量的类型,有点像C++的RTTI,常用于表达式内的语句,在定义宏时,如果需要临时变量,可以这样做:
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
它可以保证我们定义的变量_a/_b与宏传入的变量a/b类型匹配,而不会产生编译器告警。
因此container_of的第一行就是定义一个与member类型匹配的变量__mptr,赋值后,__mptr为宏参数中的待转换指针,因为只是类型转换,不涉及数据读写,((type*)0)是没有任何副作用的。
第二行用__mptr减去member变量在type中的偏移,这样便可实际访问到ptr相同偏移,也即type的实际首地址了。offsetof有两种定义:
#ifdef __compiler_offsetof #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) #else #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif
__compiler_offsetof即__builtin_offsetof,__builtin_offsetof可能是gcc內建的支持(见gcc源码c-parser.c),
从后一种实现方式可以明显看到这一技巧,假定一个从0地址开始的结构体,取其成员member的地址正是结构体内的偏移。
linux下的c语言的宏果然是博大精深呀,还得学习,下次会介绍下有关模块注册中宏的用法的~
第一次拜访客户
十二 6th
今天下午第一次拜访客户收集需求,我的感受主要有三点:
首先,直观的了解客户需要一个什么样的功能:以前听别人转述可以知道我们要实现怎样的功能,
但通常都包含了转述人对需求加工的成分,如果描述不完整还容易造成理解的偏差;今天直接听到了客户对需求的描述,我要注意自己转述的时候别扭曲了用户的原意。
其次,知道客户提出某个需求做什么用、将如何使用:客户描述了实际使用中遇到的问题,所以希望这个功能怎样怎样实现以解决这个问题。
这样便于我们理解客户提出的需求,并且站在客户的角度思考功能的实现方式。可以在一定程度上避免做出来的产品是客户不需要的,或者不符合客户的使用习惯。
最后,客户能帮助我们排除他们不会使用的场景:前期我们项目组内讨论需求时大家都尽量覆
盖猜想到的使用场景和实现方式,与客户沟通的时候他们直接回答“我们不会这么用”。
另外客户和咨询师也会顺便给出一些对产品的反馈。并且是单纯的学习产品功能不考虑用户实际使用场景时不会考虑到的。
总之收益匪浅,以后能力提高了还要主动提供解决方案供参考,以后的事儿明天再说,今天回家了先~~
需求分析小试牛刀【1】
十二 5th
上周开始可以开始参与需求工作了,暂时参与需求跟踪和需求分析两个方面,先谈谈对需求分析的认识(太教科书的东西自己已经看了很多,不再这儿赘述):
- 最初的想法:需求来源于客户,所以我们尽量采集客户的需求,然后整合规划后按照客户的希望实现即可。
- 实际情况:假设客户可以正确的表达自己的want和need,但究竟想要个怎样的产品来满足自己的want和need客户通常没想好,或者压根儿不愿意想。这个设计、实现产品的工作就需要我们来做。我们要制造需求,并培养需求。
对新需求的需求分析是从想法到产品的分析,重点在思考如何实现;
新需求实现后如果需要整合到整个产品中,就要重点分析对原有功能的影响:
- 并入需求和整个产品的风格是否一致?
- 新需求属于整个产品框架的哪部分?
- 业务流程是否有矛盾?
- 功能是否有冗余?
- 加入新功能后是否可提升产品的整体功能和竞争力?
- 新需求的数据来源于哪里?处理后流向何处?
暂时想到这些,多问些问题还是有好处的,提问有助于促进思考。
shell脚本小技巧总结【继续更新】
十二 2nd
今天写了个shell脚本,发现之前学的有关shell脚本的内容长时间不用,基本上是忘没了,所有的内容都
必须从网上现找,如判断文件是否存在等,今天就记录下学到的有关shell脚本的内容,后续有关内容也要
继续更新这篇文章的
1,判断文件是否存在
-f 判断文件是否存在
if [ ! -f $image_file ] ;then qemu-img create -b $(pwd)/images/ubuntu-base.img -f qcow2 $image_file elif [ ... ] ; then ...... fi
类似命令还有-x 判断文件是否有执行权限,-d 判断是否是路径,-eq 判断值是否相等,=直接判断是否
字符串相等
2,for loop range 的用法
for i in $(<strong>seq 1 10</strong>) ; do image_file="./images/ubuntu-${1}.img" ps aux | grep $image_file | grep -v grep | awk '{print $2}' | xargs sudo kill -9 done
主要是利用seq命令来实现
3,从ps 命令中提取指定名字的进程号,并将其killl掉
ps aux | grep $image_file | grep -v grep | awk '{print $2}' | xargs sudo kill -9 #$image_file 为进程的名字
4, shell进行算术运算
1> expr
i=7 j =8 c=`expr $i + $j`
2> let
i=7 j =8 let c=i+j
3> (())
i=7 j =8 $((c=i+j))
4> bc
echo "scale=2; 0.5 * 0.5" | bc echo "0.5*0.5" | bc -l
未完待续
近期评论