UNIX-Linux环境编程(五):进程管理

本文详细介绍了UNIX/Linux环境下的进程管理,包括基本概念如进程与程序的区别,进程分类,查看进程的方法;深入讨论了fork、vfork、进程的正常与异常退出、wait/waitpid、exec和system函数的使用,以及孤儿进程和僵尸进程的概念。
摘要由CSDN通过智能技术生成

一、基本概念

1. 进程与程序
1) 进程就是运行中的程序。 

一个运行着的程序,可能有多个进程。进程在操作系统中执行特定的任务。
2) 程序是存储在磁盘上, 包含可执行机器指令数据的静态实体
进程或者任务是处于活动状态的计算机程序。

2. 进程的分类
1) 进程一般分为**交互进程**、**批处理进程**和**守护进程**三类。
2) 守护进程总是活跃的,一般是后台运行。 

守护进程一般是由系统在开机时通过脚本自动激活启动,
或者由超级用户root来启动。

3. 查看进程
1) 简单形式 

ps
以简略方式显示当前用户有控制终端的进程信息。

2) BSD风格常用选项 

ps axu
a - 所有用户有控制终端的进程
x - 包括无控制终端的进程
u - 以详尽方式显示
w - 以更大列宽显示

3) SVR4风格常用选项 

ps -efl
-e或-A - 所有用户的进程
-a - 当前终端的进程
-u 用户名或用户ID - 特定用户的进程
-g 组名或组ID - 特定组的进程
-f - 按完整格式显示
-F - 按更完整格式显示
-l - 按长格式显示

4) 进程信息列表
◦USER/UID: 进程属主。
◦PID: 进程ID。
◦%CPU/C: CPU使用率。
◦%MEM: 内存使用率。
◦VSZ: 占用虚拟内存大小(KB)。
◦RSS: 占用物理内存大小(KB)。
◦TTY: 终端次设备号,“?”表示无控制终端,如后台进程。
◦STAT/S: 进程状态。可取如下值: 
		◾O - 就绪。等待被调度。
		◾R - 运行。Linux下没有O状态,就绪状态也用R表示。
		◾S - 可唤醒睡眠。系统中断,获得资源,收到信号,都可被唤醒,转入运行状态。
		◾D - 不可唤醒睡眠。只能被wake_up系统调用唤醒。
		◾T - 暂停。收到SIGSTOP信号转入暂停状态, 收到SIGCONT信号转入运行状态。
		◾W - 等待内存分页(2.6内核以后被废弃)。
		◾X - 死亡。不可见。
		◾Z - 僵尸。已停止运行,但其父进程尚未获取其状态。
		◾< - 高优先级。
		◾N - 低优先级。
		◾L - 有被锁到内存中的分页。实时进程和定制IO。
		◾s - 会话首进程。
		◾l - 多线程化的进程。
			◾
				◾
					◾+ - 在前台进程组中。
◦PSR: 进程被绑定到哪个处理器。
  1. 父进程、子进程、孤儿进程和僵尸进程

    1. 父进程启动子进程后,子进程在操作系统的调度下与其父进程同时运行。
    2. 子进程先于父进程结束,子进程向父进程发送SIGCHLD(17)信号,父进程回收子进程的相关资源。
    3. 父进程先于子进程结束,子进程成为孤儿进程,同时被init进程收养,即成为init进程的子进程。
    4. 子进程先于父进程结束,但父进程没有回收子进程的相关资源,该子进程即成为僵尸进程
  2. 进程标识符(进程ID)

    1. 每个进程都有一个以非负整数表示的唯一标识,即进程ID/PID。
    2. 进程ID在任何时刻都是唯一的,但可以重用,当一个进程退出时,其进程ID就可以被其它进程使用。
    3. 延迟重用。
      a.out - 1000
      a.out - 1010
      a.out - 1020
      范例:delay.c
#include <stdio.h>
#include <unistd.h>

int main () 
{
   
    printf ("进程ID:%u\n", getpid ());
    return 0;
}

二、getxxxid

#include <unistd.h>
getpid  - 获取进程ID
getppid - 获取父进程ID
getuid  - 获取实际用户ID
geteuid - 获取有效用户ID
getgid  - 获取实际组ID
getegid - 获取有效组ID

范例:id.c

#include <stdio.h>
#include <unistd.h>

int main () 
{
   
    printf ("    进程ID:%u\n", getpid ());
    printf ("  父进程ID:%u\n", getppid ());
    printf ("实际用户ID:%u\n", getuid ());
   printf ("有效用户ID:%u\n", geteuid ());
    printf ("  实际组ID:%u\n", getgid ());
    printf ("  有效组ID:%u\n", getegid ());

    return 0;
}

三、fork

#include <unistd.h>
pid_t fork (void);
  1. 创建一个子进程,失败返回-1
  2. 调用一次,返回两次
    分别在父子进程中返回子进程的PID和0。
    用返回值的不同,可以分别为父子进程编写不同的处理分支。
    范例:fork.c
#include <stdio.h>
#include <unistd.h>

int main () 
{
   
    printf ("%u进程:我要调用fork()了...\n", getpid ());

    pid_t pid = fork ();
    if (pid == -1) 
    {
   
        perror ("fork");
        return -1;
    }

    if (pid == 0) 
    {
   
        printf ("%u进程:我是%u进程的子进程。\n", getpid (),
            getppid ());
        return 0;
    }

    printf ("%u进程:我是%u进程的父进程。\n", getpid (), pid);
    sleep (1);

    return 0;
}
  1. 子进程是父进程的副本
    子进程获得父进程数据段和堆栈段(包括I/O流缓冲区)的拷贝,但子进程共享父进程的代码段。
    范例:mem.c、os.c、is.c 、mem.c

mem.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int global = 100;

int main () 
{
   
    int local = 200;

    char* heap = (char*)malloc (256 * sizeof (char));
    sprintf (heap, "ABC");

    printf ("父进程:%d %d %s\n", global, local, heap);

    pid_t pid = fork ();
    if (pid == -1) 
    {
   
        perror ("fork");
        return -1;
    }

    if (pid == 0) 
    {
   
        global++;
        local++;
        sprintf (heap, "XYZ");
        printf ("子进程:%d %d %s\n", global, local, heap);
        free 
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值