学习linux三周,越深入学越能体会到它的美妙。
说句一些人可能无法理解的话,玩linux带给我的感觉就像高中去网吧玩《穿越火线》一样着迷。
进程
我之前学习《计算机操作系统》(汤子瀛版)时,学习了一些关于进程的理论知识。
但这本书写的太理论,初学者很难读懂,不建议看这本书,我之前看的内容就基本全部忘记了。
但自从转向linux开发后,参与的项目采用多进程编程,通过linux和项目代码逐渐掌握的进程的相关概念。
在此,我建议想学习操作系统知识的朋友,在自己电脑上安装虚拟机和ubuntu系统,能学习到很多操作系统的知识。
那么,什么是进程(process)呢?
简单来说,你用手机打开微信,这就是一个进程;你再用手机打开天猫,这又是一个进程。如果你用微信和女友一边视频聊天,一边逛天猫,那么这就是多进程。
有同学说:“我手机安装了微信,这算是一个进程吗?”
答:这不是进程,手机虽然安装了微信,但它在手机中是可执行程序。只有当你打开微信后,才算是进程。
由此可得,程序是静态的,进程是动态的,它是程序执行的过程。只有当操作系统执行某个可执行程序(例如APP)时,操作系统会为该可执行程序分配相应的资源,保证其顺利执行。
进程的结构
linux下的进程包括:代码段、数据段和堆栈段组成。
代码段:手机中的任何一个APP都以一个可执行文件保存在手机中,当你运行它时,可执行程序就属于进程中代码段。
数据段:当APP运行过程中产生的各种数据,均处于数据段中。
堆栈段:当APP运行时,某些功能的实现需要调用多个函数。堆栈是用于存放这些函数的返回地址及函数间传递的参数。
**
父进程与子进程
**
在放代码之前,需要介绍一下父进程和子进程。父进程是源进程,那么子进程就是父进程的儿子,是父进程的复制。
这个概念也很好理解,大家可以想象操作系统将一个进程的数据段、代码段和堆栈段,全部复制一份放到内存中的另一个位置。被复制的进程就父进程,复制得到的新进程就是子进程。
因此,父进程与子进程除了进程号(PID,Process ID)和进程所在内存地址不同,其余部分完全一样。
Note:父进程与子进程的代码是一模一样的哦。
进程的实现
linux下进程的实现非常简单,fork()函数即可实现。fork()函数在父进程运行时,其返回子进程的ID号;在子进程运行时,其返回值为0。
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
pid_t pid;
pid = fork();//创建子进程
if(pid == -1)
{
printf("creating child process erroe.\n");//创建子进程失败时,返回-1
}
else if(pid == 0)
{
printf("this process is child process, the PID is %d\n",getpid());//子进程运行这段代码时,fork函数返回0,子进程运行时进入这个分支
}
else
{
printf("this process is parent process, the PID is %d\n",getpid());//父进程运行这段代码时,fork函数返回子进程ID,父进程进入这个分支
}
return 0;
}
下图是进程的运行结果:
从上述代码很简单,也很好理解。当父进程fork一个子进程时,你脑中就想象父进程与子进程在同时运行,且两者的代码一模一样。
当fork()返回值为0时,该进程为子进程,程序进入else if(pid == 0)这个分支。
当fork()返回值不为0时,该进程为父进程,程序进入else这个分支。
总结
今天只是简单介绍了进程的概念、进程的结构、父进程与子进程以及进程简单实现,把这些概念搞清楚了,才能继续深入学习进程的其他相关知识。
关于进程的操作还有很多,比如守护进程、进程同步和进程之间的通信等等。这些内容将在以后学习过程中慢慢总结出来。
学编程最有效的办法就是动手实现一边就全部懂了,建议大家在linux上尝试一下。
ps: 欢迎关注我的公众号[酷酷的coder],分享转行菜鸟程序员成长过程汇总的烦恼和反思.