Linux学习笔记-进程
Posted 波子木木
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux学习笔记-进程相关的知识,希望对你有一定的参考价值。
明天开始学习进程,在以前的单片机开发中,都没有进程这个概念,但从网上了解到,这个东西在操作系统中似乎具有很重要的地位,一定好好学习!
——————————————————————————————————————————————————————————————————
程序(program)是一个普通文件,是为了完成特定任务而准备好的指令序列与数据的集合,这些指令和数据以“可执行映像”的格式保存在磁盘中。例如:hello.c源程序文件经过编译后产生a.out程序,其中a.out文件为可执行镜像格式,Linux的/bin、/sbin、/usr/bin、/usr/sbin目录下保存着诸多的程序文件。
进程(process)是一个已经开始执行但还没终止的程序实例。Linux系统下使用ps命令可以查看到当前正在执行的进程。每个进程包含有进程运行环境、内存地址空间、进程ID、和至少一个被称为线程的执行控制流等资源。同一个程序可以实例化为多个进程实体。操作系统中所有进程实体共享着计算机系统的CPU、外设等资源。
Linux系统使用“ps -aux”命令时可观察到进程的当前状态:
每个进程在创建之时,系统都会给它分配一个进程ID,用来辨识当前的进程(PID),比如上图中的1,2,3,4……
那个名叫init的进程,就是一切进程的母亲,所以她的进程ID是1。
创建进程的函数,名叫fork,这个函数虽然没有参数,但它的返回值——非常重要。
一般在调用fork来创建了一个进程后,程序立即会分离出两条完全不干扰的线路,分别运行两个程序,其中一个叫爹进程,一个叫儿进程。
爹进程和儿进程所运行的代码都是完全一样的,而且所拥有的资源也是完全相同,那么该怎么区别这两个进程呢?就需要用到fork函数的返回值了。
“fork()函数将运行着的进程分裂出另一个子进程,它通过拷贝父进程的方式创建子进程。子进程与父进程有相同的代码空间、文件描述符等资源”
fork函数如果成功创建了进程,那么分别会返回两个大于零的数,对于爹进程来讲,它返回它所创建的那个儿进程的PID,对于儿进程来讲,它会返回零。
(fork函数会返回两个返回值,而我们对返回值进行判断,便可清晰地分辨出哪个是爹,哪个又是儿!)
理论知识便到此,下面开始学习这个fork函数的使用。
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<errno.h> 4 5 6 void main(void) 7 { 8 pid_t pid; 9 10 pid = fork(); 11 if(pid < 0) 12 { 13 printf("进程创建错误,错误编码:%d.\\n",errno); 14 return; 15 } 16 else if(pid == 0) 17 { 18 printf("我是儿子,我叫%d,我爹叫%d.",getpid(),getppid()); 19 } 20 else 21 { 22 printf("我是爹,我叫%d,我儿子叫%d.",getpid(),pid); 23 } 24 25 return; 26 }
花了几分钟,将代码写完,虽然比较简单,但也能够熟悉fork函数的使用方法了。
然后写makelove文件。
1 EXE=process 2 SRC=process.c 3 OBJ=process.o 4 5 cc=gcc 6 CFLAG=-g 7 LCDFLAG= 8 9 10 EXE:$(OBJ) 11 $(cc) $(LCDFLAG) $(SRC) -o $(EXE) 12 13 OBJ:$(SRC) 14 $(cc) -c $(SRC) -o $(OBJ) 15 16 .PHONY:clean 17 clean: 18 rm -vfr $(OBJ) $(EXE)
好!现在开始进行编译。
完美编译,没有爆出任何错误和警告。
下面开始执行!
等等……代码出现了问题!
他爹都说了,他的名字叫8171,他儿子的名字叫8172.但是……这个儿子似乎有点不认他爹啊!
他的名字叫8172,这没有错,但为什么他说他的爹成了1呢?
据我所知,这个1所代表的是init进程。
难道?
他有奶便是娘?他是个六亲不认的逆子?
我不相信我手上会写出这么一个不认父亲的混账玩意儿,开始查资料……
——————————————————————————————————————————————————————————
查了半天,终于找到原因了,原来并非是8172不认他爹,其实这也怪我,我还没等他长大,就当着他的面,亲手把他的爹给杀死了!
为了在这个炎凉的世间活下去,他不得不认贼作父,这也是为了生存啊!!!
else if(pid == 0) 17 { 18 printf("我是儿子,我叫%d,我爹叫%d.",getpid(),getppid()); 19 } 20 else 21 { 22 printf("我是爹,我叫%d,我儿子叫%d.",getpid(),pid); 23 } 24 25 return;
问题出现在这里,由于他爹毕竟是成年人,跑得当然比一个刚出生的婴快,在他儿子还没有反应过来之前,就已经跑完了短暂的一生……
执行了return语句,学过C语言的同学都知道,如果程序调用的return,那么也就意味这个程序的终止,系统会收回他曾经拥有过的一切,包括名字(PID)。
现在修改代码,让他爹别死那么快,至少儿子在长大之前。
#include<stdio.h> #include<unistd.h> #include<errno.h> #include<stdlib.h> void main(void) { pid_t pid; pid = fork(); if(pid < 0) { printf("进程创建错误,错误编码:%d.\\n",errno); return; } else if(pid == 0) { printf("我是儿子,我叫%d,我爹叫%d.\\n",getpid(),getppid()); } else { printf("我是爹,我叫%d,我儿子叫%d.\\n",getpid(),pid); } wait(NULL); // 儿子还没长大,我还不能死!不然他该不认我了! return; }
在程序中加入了一个wait函数,这个函数相当于是ICU,可以延缓病人的生命,用来等待见自己亲人最后一面,用来等待子进程的结束,如果子进程没有结束,那他心中极度不甘。
父进程会用尽全身的力气,憋住最后一口气,死死得等在这里,一直等到子进程结束为止。
直到儿子长大成人,能对祖国和人民作出贡献之后,父亲才不带着悔恨离开这个世界!
真是令人感动的代码…………
我已经被感动得流下了眼泪,含着泪,又执行了一遍代码:
终于,儿子在父亲断气之前,亲口喊了一声:“爸爸!我是8251,我是你的儿子8251啊!!”
父亲看着儿子泪眼婆娑的模样,心中再没有了遗憾和留恋,只剩下无限的欣慰……
“有儿如此,我8250可以含笑九泉了!”
以上是关于Linux学习笔记-进程的主要内容,如果未能解决你的问题,请参考以下文章