Linux下进行应用代码开发,类似于windows,在系统资源充足,cpu处理能力足够强时,可忽略对代码的选择。可是实现进行任何代码功能的开发,完全可以充分利用每种代码的优势和特性。除非对性能的极致压榨,完全无需过多考虑内存管理和性能问题。
但当进行嵌入式小系开发或产品设计时,为追求成本,不断的根据需求降低产品中的CPU。这也导致CPU的性能只是足以支撑项目开发的使用,而无法肆意使用过多的语言和库。而对应用的开发使用中,能够直接使用的即是最基础核心的的C语言和C++,但对于一些做嵌入式开发的团队,在长期使用MCU的团队中,能够熟练而优雅的使用C语言,反而不具备C++的开发能力。这时会考虑优先在Linux应用中优先使用C进行开发,这对于整个团队是友好的,而且开发效率更高。但使用中会发现C的标准库并不多,当然对于C的使用基本是满足的。但在Linux的应用环境中最常见的多进程的使用的以及多线程的使用,而Linux在C的系统中仅仅提供了进程间通信的方式,虽然Linux下的线程本就是进程,这导致线程间通信方式要么使用进程通信方式,要么手动实现相应的通信方式,如果仅仅针对的是一两个项目固定平台也是能够完美优雅的开发。但这与Linux平台下通用接口设计并不符合,为了适应更多硬件平台的应用和开发,则需要考虑到多核CPU,单核CPU,DMA,cache的问题,以及各种应用场景的适应性问题;同时也在实际开发中增加了一定的开发成本和维护成本。而这部分成本是STL中不存在的。
那如果考虑使用C++进行项目开发呢?C++是C语言的补充,是完全兼容C语言的,同时又在C语言上主要添加了类,容器,模板类,命名空间和迭代器等内容,以及第三方开发库。在于小型系统开发时,并不会使用所有东西,那在C++中使用C开发同时使用C++补充的部分特性便能更好满足当下的需求,虽然对于团队提高了一定的开发成本,但也并不会太高;这也会逐渐打破团队C语言以及C++的使用壁垒,也不需要考虑自己开发维护通用库的成本。
内容中技术的进一步说明:
-
Linux下不存在线程
linux的系统提供了fork方式去创建进程。而POSIX提供了pthread已支持创建线程,但实际他们的本子没有太大区别。都是使用系统调用clone,只是参数不同而已。- pthread_create调用如下:clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,0),父子俩共享虚拟地址空间、文件系统资源、文件描述符和信号处理函数及信号。
- fork调用如下:clone(SIGCHLD,0)
- vfork调用如下:clone(CLONE_VFORK | CLONE_VM | SIGCHLD,0)
创建子进程,则是注册一个SIGCHLD信号,当子进程终止时,会向父进程发送一个SIGCHLD信号。
-
进程通信(IPC)在线程间使用
如上说书,Linux中既然只有进程,不存在线程,那只有进程便是合理的。那对于使用pthread_create创建的线程使用进程通信方式也是没有问题的。实际使用中的确是可以这样使用。
进程是多个线程的合集,进程之间是完全独立的,不存在资源共享,只有实际硬件是共享的。而线程则不同,线程存在同于一个进程,他们既资源共享,也内存共享。而对于Linux提供的进程通信机制更适用进程的特性,而对线程这一特性并不是十分友好。例如Linux进程通信机制提供的机制(如消息队列)生存周期是跟随与系统内核,从创建开始一直到内核结束,当然也可以通过接口去手动删除。但当某个进程崩溃时,如果没有处理好进程通信调用,便会导致该调用无法回收,这可能是一种灾难;当然也可为解决此类问题创建一系列回收机制,但这部分开发不是实际项目说需求的,也导致了开发和售后成本的变相增加,这是与需求不符的。
C和C++杂记
- std:cout和printf
- std:cout存在缓冲机制,且线程加锁位置是缓冲输出到终端时。
- printf不存在缓冲机制,且线程加锁位置是整个过程。
- 同一进程两者混用会导致输出结果不预期,严重导致内存溢出(coredump)