linux进程一章知识总结

linux进程总结

指令:基础的计算机动作
程序:机器代码指令和数据的集合
进程:一个程序的具体实现,进程是运行中的程序

先来复习进程的查看:

1、ps:      参数选项:
        -e:显示所有的进程    -f:全格式显示        -h:不显示标题
        -l:长格式输出       -a:显示终端所有进程   -r:只显示运行的进程  
2、who:
3、w:比who好用,可以看到具体的统计数据
4、top:显示运行中系统动态实时视图
5、pstree:查看进程树的样貌,可以明显的理清进程间的关系。

进程的状态有:运行状态(running)、可中断等待状态(sleeping)、不可中断等待状态(uninterruptible sleep)、僵死状态(zombile)、停止状态(traced or stopped)。

注:进程中带[ ]的是kernel(内核)的一部分,装扮成进程,方便操作系统管理。init作为第一个系统创建的进程,该进程一直存在,知道电脑系统关闭。kernel(内核)开机的时候通过kernel_thread(init ,NULL,0)创建init进程,以后的进程都由init创建得到,进程存活在内存里面。

一、创建一个进程:

注:创建进程按创建者可分:操作系统创建和父进程创建。系统创建进程存在平等关系,一般不存在资源的继承;父进程创建的进程存在隶属关系。

1、fork:fork调用成功,父子进程在调用fork的地方分开,fork函数给子进程返回0,给父进程返回创建成功的子进程的pid。
函数原型:

#include <sys/types.h>
#include <unistd.h>
pid_t  fork(void);

注:其实pid_t一般就是一个整型数(int),可是有的系统对 pid_t的定义是long型的,所以在使用的时候左值最好还是pid_t定义类型的吧。

2、vfork:vfork函数相对于fork函数的优点:
a、fork一个进程后,父子进程的先后顺序不定,而vfork函数创建一个函数后确保了子进程先于父进程运行。
b、fork时子进程完全复制父进程的资源,无论是全局还是局部变量独立于父进程具有良好的并发性;后者父子进程共享同一地址空间,减少系统开销。

综合fork和vfork我们来看个例子:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int         globalvar = 5;
int main(void)
{
    pid_t    pid;
    int      var = 1;
    int      i;
    printf("to see the differences between fork and vfork:\n");
    pid = fork();
//  pid = vfork();
    switch(pid)
    {
        case 0:
            i = 3;
            while(i > 0)
            {
                printf("i am the child !\n");
                globalvar++;
                var++;
                i--;
                sleep(1);
            }
            printf("i am child, my globalvar is %d, my var is %d\n",globalvar, var);
            break;
        case -1:
            printf("failed to creat a child!\n");
            break;
        default:
            i = 5;
            while (i > 0)
            {
                printf("i am the father!\n");
                globalvar++;
                var++;
                i--;
                sleep(1);
            }
            printf("i am father, my globalvar is %d, var is  %d\n",globalvar, var);
            break;
    }
    exit(0);
}

分别用fork和vfork进行运行的得到的结果如下:
fork:

vfork:

结论:fork:子进程数据独立,无论全局变量还是局部变量。
vfork:子进程先于父进程执行,父子进程共享一段地址空间。

二、创建一个守护进程

守护进程:守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断。eg:internet服务器进程inetd,web服务器进程http等等。
流程:

相关知识:

进程组:是一个或多个进程的集合。进程组由进程组ID来唯一标识。除了进程号(PID)之外,进程组ID也是一个进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因组长进程的退出而受到影响。可以通过<unistd.h> 中的int getpgrp(void) 获取当前调用进程的组id;可以通过int setpgrp(void) 调用进程独立成为一个组,并成为该组的组长。
会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。
文件权限掩码:文件权限掩码是指屏蔽掉文件权限中的对应位。
setsid函数在程序中起的作用:摆脱原会话的控制、摆脱原进程组的控制、摆脱原控制终端的控制

三、执行新的进程

(偷换进程:执行一个可执行的程序以代替当前进程的执行映像;把一个新程序装入调用进程的内存空间,改变调用进程的执行代码,但是没有改变进程标示符号, 所以并没有创建新的进程)
exec函数族:

#include <unistd.h>
extern char **environ;
1int execl(const char *path, const char *arg, ...);
2int execlp(const char *file, const char *arg, ...);
3int execle(const char *path, const char *arg, ..., char * const envp[]);
4int execv(const char *path, char *const argv[]);
5int execvp(const char *file, char *const argv[]);
6int execve(const char *path, char *const argv[], char *const envp[]);

函数调用失败返回 -1 。
1,2,3:函数需要一一输入命令行参数,要以NULL或者(char*)结束。
2,5:函数输入的是文件的名字,函数会自动到环境变量PATH制定的目录里找到完整的路径。
6,:函数才是真正意义上的系统调用,其他为这基础上的包装库函数。

**注意:
1、第二个参数开始的参数构成了参数列表;按照惯例, 参数列表的第一个参数是不带路径的程序文件名。
2、如果程序中打开过一些文件, 执行exec函数族之后,这些文件任然保持打开。执行关闭位, 当被设置时, 如果执行exec文件自动关闭。<fcntl.h>中的函数fcntl(fd, F_SETFD,1),表示执行关闭,函数返回1, 0为撤销设置。

四、等待进程的结束

当子进程先于父进程结束的时候,如果父进程没有调用wait/waitpid给子进程“收尸”,子进程就会进入僵尸进程的状态。
因为:一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁, 而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是 使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。
函数原型:

#include <sys/types.h>
#include <sys/wait.h>
pid_t   wait(int *statloc);
pid_t   waitpid(pid_t pid, int *statloc, int options);

函数说明:
1、wait等待第一个终止的子进程,waitpid等待指定的子进程。
waitpid中pid > 0:等待为该pid的子进程;pid = -1:等待任一进程;pid < -1:等待其组id等于绝对值的任意子进程;pid = 0:等待调用进程组的任一子进程。
2、statloc是用于存放子进程的退出码。
3、wait调用,父进程处于阻塞的状态;而调用waitpid可以将第三个参数改:WNOHANG,使父进程不被挂起。

五、进程的结束

1、return:将控制权交给主调函数。
2、_exit():头文件<unistd.h>,直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构。将控制权给系统。
3、exit():头文件<stdlib.h>, 在_exit()的基础上调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是”清理I/O缓冲”。将控制权交给系统。
4、kill:先用ps -ef 查看进程的pid,kill pid 杀死进程;此外:kill -9 pid是绝杀;还有一个有趣的:在终端输入xkill回车,然后点击你想杀的了,可以试试。
5、abort:用于异常终止。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值