Linux — 进程管理

时间:2020-12-19 12:44:50   收藏:0   阅读:3

进程创建

进程通过fork()创建的大致过程:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

extern int create_process(char* program, char** arg_list);

int create_process(char* program, char** arg_list){
    pid_t child_pid;
    child_pid = fork();
    if(child_pid !=0 ){
        return child_pid;
    }else{
    execvp(program, arg_list);
    abort();
    }
}

概览图:

技术图片

编译知识

静态库

这里额外补充一些编译相关的内容。一个源码文件要变成可执行的程序,需要经过编译、链接。

技术图片

这里编译出的.o文件,就是ELF的第一种类型,可重定位文件,格式如下:

技术图片

在程序中我们提到过函数栈,局部变量是放在里的,在运行期随时分配、随时释放。这里讨论的是文件,还没到执行阶段。

如要将函数作为库文件被重用,不能以.o的形式存在,而是要形成库文件,最简单的类型是静态链接库.a文件。

ar cr libstaticprocess.a process.o
# 形成二进制执行文件staticcreateprocess
gcc -o staticcreateprocess createprocess.o -L. -lstaticprocess

上述第二条命令链接时,createprocess.o调用了create_process函数,但不知道位置,通过将process.o合并进来,就可以确定位置了。这里形成了ELF的第二种格式:

技术图片

.o相似,文件被分为多个section,通过节头表来描述。这里除了段描述之外,最重要的是p_vaddr——加载到内存的虚拟地址。

静态库特点:

动态库

当动态链接库被链接到一个程序文件时,最后的程序文件并不包括动态链接库中的代码,而仅仅包括对动态链接库的引用,并且不保存动态链接库的全路径,仅保存其名称

gcc -shared -fPIC -o libdynamicprocess.so process.o

gcc -o dynamiccreateprocess createprocess.o -L. -ldynamicprocess

执行此程序时,先寻找动态链接库,再进行加载。默认,系统在/lib/usr/lib 路径下寻找,找不到则报错。可以通过设定LD_LIBRARY_PATH环境变量,指定动态链接库的路劲。

动态链接库,就是ELF的第三种类型,共享对象文件

接下来,我们来看下程序运行时,是如何将so文件动态链接到进程空间的?

运行程序为进程

ELF二进制文件是如何加载到内存里的?

static struct linux_binfmt elf_format = {
        .module         = THIS_MODULE,
        .load_binary    = load_elf_binary,
        .load_shlib     = load_elf_library,
        .core_dump      = elf_core_dump,
        .min_coredump   = ELF_EXEC_PAGESIZE,
};

具体调用链:do_execve->do_execveat_common->exec_binprm->search_binary_handler。

在系统调用时,exec最终调用的是load_elf_binary.

技术图片

进程树

所有进程的祖宗进程,就是系统启动时的init进程。init进程会启动很多daemon进程,为系统运行提供服务。然后启动getty,让用户登录,登录后运行shell。

技术图片

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!