Linux应用编程学习记录(四)

2019-07-13 06:37发布

        今天开始学习关于进程的相关知识,参考的教材依然是周立功的《嵌入式Linux开发教程(上册)》,内容相当于第12章。因为没多少机会写代码来体会,这部分内容可能会比较抽象,难以理解。总之一个一个来吧。         初识进程 1.  进程是一个已经开始执行,但是还没终止的程序实例。   2.  进程是一个动态的实体,它是如何从静态的程序转换而来呢? 首先要创建一个新的进程,然后在新进程中装载程序文件,并执行文件的main函数 PS: 关于这个main函数比较有意思,通常它被作为程序的起点。main函数有三种原型定义: int main() int main(int argc, char *argv[]); int main(int argc, char *argv[], char *env[]); 来关注一下最后一种形式吧,因为他最全面嘛,搞懂了它就万无一失了。三个参数: 第一个是整形,代表命令行参数的数目 第二个是字符型指针数组,大小不定。即它是若干个指向字符型变量的指针所构成的数组。如果把命令的各个参数都当成字符串,那么这里的每个元素都指向各个字符串的首地址。注意,argv[0]这个元素指向的是程序的名称。 第三个也是字符型指针数组,大小不定。因为程序执行中,可能会有各种环境变量发生作用,这个数组中各个元素分别指向各环境变量。还有个疑问(环境变量都是字符串?)   3.  进程的状态 比较多,我也记不清,总之来一张图吧 使用命令  ps -aux 后,观察STAT列,第一个字符就代表该进程当前状态   4.  每个进程在创建时,都被内核分配一个ID,常被称为PID。PID是一个整型数据,当进程退出时,这个数值可以被回收再利用。使用getpid()函数可以获取当前进程的PID。 比如像这样写: printf("current process pid is %d ", getpid()); PS:我查了下,getpid这个函数的头文件是unist.h   5.  UID和GID         Linux中每个用户有一个用户ID,称为UID;每个用户所在的组有一个组ID,称为GID。为什么要扯这个,他与进程有什么关系?         这决定了进程的权限。在Linux中对不同的用户和组进行了非常明确的权限划分,不同的用户和组所具有的权限是不同的。当执行一个程序时,该程序会获取当前用户的UID和GID,并且以此来作为进程的权限。   6.  父进程和子进程         进程可以创建新的进程,这两者一个是父一个是子。因此父进程和子进程都是相对概念。         Linux中,所有的进程如果都套用这个父子进程的概念,可以将它们组织成一个树状结构。这棵大树的根基是init进程。也就是说所有的进程都是通过它衍生出来的。         输入 pstree命令可以以树状结构显示所有进程,不过我在root权限下这么做了,发现根基并非init,而是systemd。上网查了下,init作为根基和systemd作为根基,可以说是两种启动方式。概念上是并列、平级的。用了一个,另一个就不需要用了。init是比较老的,而systemd比较新。init应该是类似串行的执行方式,而systemd是并行的执行。具体的暂时没空去研究,以后再议吧。   7. 关于环境变量         上面提到了进程运行中需要用到环境变量,那么如何获取这些环境变量呢?方法有三 其一,就像上面讲的那样,使用main函数的第三个参数 char *env[],注意数组的最后一个元素是NULL。像书上那样写个代码测试下吧。 运行后,把一大溜的环境变量都打印了出来。 从打印的结果来反推,这是用puts一行行打印出了环境变量。因而这每一行都被视作字符串,它们的首地址传给了main函数的参数env。 其二,利用全局变量environ,该变量是一个指向字符型指针的指针,即 char **environ 教材上利用下面的代码,也能实现和刚才一样的效果: 关于这个environ全局变量,我认为以下猜测应该是基本靠谱的: 其三,利用函数getenv函数获取环境变量。 该函数的定义: char *getenv(const char *name); 示例: char *env; env = getenv("HOME");   8.  标准IO         每个进程创建时,系统都会自动打开3个文件,标准输入、标准输出和标准错误输出。既然是文件就会有句柄,它们分别是0、1、2。         教材上指出:         但是我感觉,既然你已经知道了这三个文件的句柄,如果需要用到的话。直接写数字就好了呀,为什么要整这么麻烦,用宏去替代呢~是不是也会偶发像上次使用open函数,指定生成文件的权限时一样的问题:在系统版本升级或者变迁的时候,因为底层实现代码的改变,导致应用层只认这种助记符一样的宏。