作为一名程序员,我们天天都在与代码打交道,但你是否有了解过我们的程序是如何在操作系统中运行与调度的呢?如果你对进程与计算机不甚了解,那么本文将带领你走向操作系统进程的第一步。
在了解进程的相关知识前,我们需要先了解以下计算机的组成体系及其概念。
冯诺依曼体系结构是一种计算机的组成方案,因为使用其体系构造的计算机性价比很高,所以我们日常生活中使用的计算机,如笔记本、服务器等大部分都遵守着冯诺依曼体系结构。
冯诺依曼体系结构规定了计算机由五个部分组成,控制器、运算器、储存器、输入设备、输出设备。
注意:
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS),笼统的理解,操作系统包含:
操作系统是纯正用于管理的软件,操作系统与硬件交互,管理所有的软硬件资源。
如果你没有学习过系统知识,可能会以为进程就是把二进制程序拷贝执行而已,但其实进程指的是PCB(process control block)+ 可执行程序
PCB又名进程控制块,这是一个进程属性的集合体,用于描述进程,在linux内核是一种链式结构(task_struct),它会被装载到内存中。
在Linux里面描述进程的结构体就叫做task_struct,其内容分为:
进程的信息可以通过linux目录中的/proc文件夹来查看
或者你也可以用top / ps 等指令工具来获取
在Linux平台下,C语言可以用fork函数来创建子进程,父子进程代码共享,当数据使用写实拷贝,当数据没被修改时,数据共用。
#include
#include
#include
int main() {
//fork如果创建子进程成功则返回0,失败返回-1。
pid_t id = fork();
if(id == 0)
{
printf("我是子进程\n");
}
else
{
printf("我是父进程\n");
}
return 0;
}
在Linux中进程拥有多种状态,一个进程可以有多个状态。让我们来看看Linux内核里面对进程状态的定义吧。
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
我们可以通过top指令或ps指令来检查进程
僵尸进程是一种比较特殊的状态,当子进程退出,而父进程没有读取到子进程的返回码时就会产生僵尸进程。因为僵尸进程还没被系统清理其开辟的空间,所以僵尸进程还会导致内存泄漏。
C语言创建僵尸进程:
#include
#include
int main()
{
pid_t id = fork();
if(!id)
{ //C语言可以通过getpid指令来获取进程的id
printf("child[%d] is return....\n", getpid());
sleep(2);
exit(EXIT_SUCCESS);
}
else
{
printf("parent[%d] is sleeping...\n",getpid());
sleep(10);
}
return 0;
}
孤儿进程和僵尸进程恰好相反,如果父进程先退出,子进程继续运行,那么子进程就会成为孤儿进程。成为孤儿进程后,就被交给pid为1的进程管理,也就是系统。
来段代码:
进程优先级
基本概念
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整
体性能。
查看系统进程
在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
#include
#include
#include
int main()
{
pid_t id = fork();
int i = 0;
if (id == 0)
{ //child
while(i++ < 10)
{
printf("[%d] : child_pid[%d] : parent_pid[%d]\n", getpid(), getppid());
sleep(1);
}
}
else
{ //parent
printf("parent[%d], is exit\n", getpid());
exit(0);
}
return 0;
}