初学Linux进程控制编程

来源:互联网 发布:高斯分布 python 编辑:程序博客网 时间:2024/05/20 02:26

Linux进程

Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。
也就是说,每个进程都是一个独立的运行单位,拥有各自的权利和责任。其中,各个进程都运行在独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。

获取进程

我们知道, 每个进程都有一个ID, 那么怎么得到进程的ID呢?
系统调用getpid可以得到进程的ID; 而getppid可以得到父进程(创建调用该函数进程的进程)的ID; 此外, getuid可以的到启用该进程的用户ID。

创建进程

通过fork函数创建进程。 我们可以通过查询man手册获得fork函数的描述:
fork

小程序

下面我们通过一段小程序进一步理解进程的独立运行以及进程的ID。

#include<stdio.h>#include<sys/types.h>#include<unistd.h>int main(){    int a = 10;    pid_t pid = fork();    if (-1 == pid)    {        perror("fork");        return 1;    }    if (0 == pid)    {        printf("child pid = %d, ppid = %d\n", getpid(), getppid());        a = 11;        printf("a = %d\n", a);    }    printf("----------\n");    if (pid > 0)    {        sleep(1);        printf("return value = %d, father pid = %d\n", pid, getpid());        printf("a = %d\n", a);    }    return 0;}

程序运行结果

result

程序解读

1.这段代码在两个进程中均被访问(程序中printf(“———-\n”)被执行了两次说明了这一点);
2.若fork创建进程成功, 父进程和子进程得到的fork()的返回值不同, 父进程的得到的返回值是子进程的ID(>0), 子进程得到的返回值为0, 因此, 两个进程分别进入了两个不同的if语句(多进程)。
3.为什么子进程和父进程中打印的a的值不同?
在使用fork()创建一个进程时, 子进程只是完全复制父进程的资源, 复制出来的子进程有自己的task_struct结构和PID, 但却复制父进程其他所有的资源。 这样得到的子进程独立于父进程, 具有良好的并发性, 但是在二者之间的通信需要通过专门的通信机制, 如pipe、共享内存机制等 (在不使用任何通信机制时, 父、子进程不相互影响)。 这就相当于有两个人同名, 甚至他们穿的衣服都相同, 但他们仍是两个独立的人, 打了其中一个人的脸一下, 另一个人的脸并不会肿起来。
4.在使用fork()时, 复制父进程的所有资源, 开销比较大。而Linux中为了降低开销, 采取了copy-on-write(COW写时复制)技术。
写时复制推迟了真正的数据复制, 在fork最初并不会真的产生两个相同的复制, 若后来确实发生了写入, 那意味着父进程和子进程的数据不一致了, 这时才产生复制动作, 每个进程拿到属于自己的那一份。
5.a的值在子进程中发生改变, 由于不知道子进程和父进程的执行顺序(有可能父进程在a的值发生改变之前将a的值打印出来), 为了使程序更有说服力, 在对应父进程的if语句中, 加入了sleep(1)语句, 使父进程睡眠一段时间。

好了, 通过这段程序我们对Linux下的进程有了更加直观的认识。