头条不止是阅读,还有分享,更有IO币。可以兑换机械键盘、技术图书喔。 欢迎分享:http://toutiao.io/contribute 前面做了一些Windows服务端程序向Linux服务端程序的移植工作,还是有些收获的,这里整理记录一下,将工作内容和细节方面的东西供大家参考。同时需要说明几点:这里的移植是真的移植,而不是考虑跨平台开发型的;这里的移植是针对无界面形式的程序,主要是服务端程序;那啥wine、mono的太大,就不考虑了。 一、数据类型定义1.1 数据类型的差异Windows和Linux的数据类型定义完全是两个风格,而且Windows的类型定义喜欢用大写字母,Windows的数据类型主要是定义在windef.h这个头文件里面的,可以将简单的数据类型按照目标机器翻译过来,当然也有些定义比较的复杂,不过很多却是没用的,可以安全的删掉。 1.2 函数接口的差异Windows也是支持POSIX标准的,所以大多数的底层函数还是可以用的,但是某些函数的名字和参数签名等还是有些差异(比如stricmp/strcasecmp),如果要在这个头文件里面处理,可以内联封装加进去。 二、进程间的通信2.1 创建线程Windows使用CreateThread创建线程,而Linux通常使用pthread线程库来实现多线程。 2.2 多线程以及进程间同步在Windows上面,除了CriticalSection是仅限线程间的同步之外,其他Mutex、Event、filemap,在使用的时候,只要设定了lpName,那么就可以在其他进程中用这个名字打开,就算是进程间的同步和通信了,否则的话就是线程间的同步。
shm和mmap其实都差不多,但是如果有些数据不像映射到硬盘文件系统上(比如处于保密安全考虑),那么就推荐使用shm来实现。 三、定时器在Windows下面,调用SetTimer创建定时器的时候可以指定ID,一个进程中可以创建很多个定时器,但是在Linux下就没有这么方便了。alarm/sleep都是用SIGALRM来实现的,而且代码没法异步执行;timer_create可以指定发送的SIGNUM,然后可以利用调用sigaction提供的参数来区别各个定时器,当然是个候选的方式;同时我找到的网络还有推荐的是使用timerfd epoll来实现,本库就是按照这个实现封装来模拟SetTimer的操作。 看似后面两者都可以实现多定时器,实际还是有些差异,前者设定信号处理函数,但是信号处理函数是异步的,所以在这种情况下所做的事情有限,而后者使用一个线程专门检测执行信号处理函数,算是一个进程同步上下文,虽然精度有所欠缺(比如只能按顺序检测没法按照真正时间排序),但是使用更加方便安全。 四、网络IO复用4.1 数据和函数定义细节差异Windows针对自己的异步IO添加了一系列的宏,比如WSAEFAULT、WSANOTINITIALISED等,以及WSAGetLastError等函数(这个直接用errno模拟了)。 4.2 网络IO复用虽然都是事件驱动的网络IO复用技术,但是算是两者网络风格最大的不同了。 4.2.1 Windows平台Windows采用完成端口(Completion Port)的方式,一般的操作步骤是: 4.2.2 Linux平台Linux有经典的select、poll,以及后面增强型的epoll方式,目前epoll有很多优点(侦听socket数目多、效率高等),所以没有特殊利用就用epoll吧,epoll的操作步骤是: 五、其他方面5.1 调试技术有时候程序写多了,莫名其妙的Segmentfault,如果没有调试信息会让人一脸萌逼不知所措。针对这类情况,可以: 5.2 单链表Linux内核有个大名鼎鼎的list_head,可以封装在数据结构中使用,十分方便。但是这东西默认是内核态的,所以做了一点点修改,就可以在用户态方便的使用了。 移植的代码已经托管到st_utils了,欢迎大家测试指正。同时由于工作的时间比较的旧,很多参考文献不能一一列出了,如原作者有需求,请联系我加上! 本文完! 参考文献
更多优质内容,欢迎安装、使用《开发者头条》iOS、Android 客户端。 体验地址:http://toutiao.io/download
本文转载自:微信公众账号 - developerWorks,版权归原作者所有! | |||||||||||||||
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|