进程

2019-06-16  本文已影响0人  loopppp

基本概念

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

       pid_t getpid(void);
       pid_t getppid(void);
  1. 文本段:又称为代码段,存放所执行程序代码的机器指令,具有只读属性
  2. 已初始化数据段:存放已经初始化过的全局变量和静态变量
  3. 未初始化数据段:存放未经初始化的全局变量和静态变量
  4. 栈:这是一块可动态变化的内存区,由一个个栈帧组成,系统会为每一个函数调用分配一个栈帧,里面存放该函数的局部变量,实参以及返回值。栈驻留在高地址处并向下增长(也有例外的实现),栈帧中还会保存有一些cpu寄存器的值,比如程序计数器;每当函数嵌套调用另一个函数时,会在被调用函数的栈帧中保存这些寄存器的副本以便函数返回时将寄存器恢复
  5. 堆:可以在运行时进行动态变化的内存区

虚拟内存简介

  1. 把进程的地址空间分割成一个固定大小的页,同时也把实际物理内存空间也分为一片片同样大小的页。在一个程序运行的任意时刻,该进程的有效地址空间可以分为两部分,驻留在物理内存中的内存页以及保留在磁盘上的内存页(一般放置在swap交换分区中)。所以内核会为每个进程都维护一张页表,用来记录有效地址内存页当前是在物理内存中还是在磁盘上
  2. 如果进程在页表中未找到需要的内存页,这时候发生缺页中断,内核挂起当前执行的进程,同时从swap分区将所需要的内存页调入内存
  3. 如果进程所访问的内存页属于无效地址空间,即在页表中找不到,这时候进程会收到SIGSEGV信号,默认动作是终止该进程并转储
  1. 栈向下增长,可能是因为嵌套函数调用或者在一个栈帧中分配了大量局部变量
  2. 在堆中调用malloc等函数分配了内存
  3. 调用mmap创建内存映射
  1. 提供了多个进程共享内存的方法
  2. 提供了内存保护机制,可以对页表项进行标记,分为可读可写可执行
  3. 可以执行超出大于物理内存的程序
  4. 进程之间相互隔离,不能随意访问各自的地址空间
  5. 对于编译器和连接器以及程序员来说,不需要去关注实际的物理内存

进程的环境变量

#include <stdlib.h>

//检索单个名字为name的环境变量值,返回value
char* getenv(const char* name);
//向当前进程的环境变量表中添加一个新的环境变量,string必须是"name=value"的格式
int putenv(char* string);
//添加一个新的环境变量,只需填入name和value,不需要"=";并且overwrite非0时覆写原变量
int setenv(const char *name, const char *value, int overwrite);
//删除名字为name的变量
int unsetenv(const char *name);
//清除所有环境变量
int clearenv(void);

setjmp和longjmp

#include <setjmp.h>

int setjmp(jmp_buf env);

void longjmp(jmp_buf env,int val);
  1 #include <setjmp.h>
  2 #include "sysHeader.h"
  3 
  4 static jmp_buf env;
  5 void f2();
  6 
  7 void f1()
  8 {
  9     if(setjmp(env) != 0)
 10         printf("经过f2跳转,第二次调用setjump\n");
 11     else
 12         f2();
 13 }
 14 
 15 void f2()
 16 {
 17     printf("调用f2,执行longjump\n");
 18     longjmp(env,1);
 19 }
 20 
 21 int main(void)
 22 {
 23     f1();
 24     return 0;
 25 }

内存分配

       #include <unistd.h>

       int brk(void *addr);

       void *sbrk(intptr_t increment);
       #include <stdlib.h>

       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);
       void *reallocarray(void *ptr, size_t nmemb, size_t size);
        #include <alloca.h>

        void* alloca(size_t size);

进程的创建和终止

       #include <unistd.h>
       void _exit(int status);

       #include <stdlib.h>
       void exit(int status);
  • WIFEXITED(status),如果子进程正常结束则返回true,并可以使用WEXITSTATUS(status)取得进程的退出值
  • WIFSIGNALED(status),如果通过信号杀掉子进程则返回true,这时可以使用WTERMSIG(status)返回导致该进程终止的信号编号
  • WIFSTOPPED(status),如果子进程因为信号停止则返回true,这时可以使用WSTOPSIG(status)返回导致该进程停止的信号编号
  • WIFCONTINUED(status),如果子进程因为收到SIGCONT信号而恢复执行则返回true

程序的执行

函数 对程序文件的描述 对参数的描述 环境变量来源
execle 路径名 列表 指定envp参数
execlp 文件名+path 列表 调用者的envp参数
execvp 文件名+path 数组 调用者的envp参数
execv 路径名 数组 调用者的envp参数
execl 路径名 列表 调用者的envp参数
进程属性 exec() fork() 说明
文本段 共享 -
栈段 -
数据段和堆段 -
环境变量 见说明 除了带有e的exec函数会修改环境变量,其他都是继承原来的
内存映射 -
内存锁 -
进程ID -
父进程ID -
进程组ID -
会话ID -
实际ID(用户和组) -
有效和保存设置ID 见说明 根据待执行的可执行文件是否设置了设置用户或者组ID位来决定
打开的文件描述符 见说明 如果fd设置了close-on-exec位,则不保存
close-on-exec标志 -
文件偏移 共享 -
打开文件状态标志 共享 -
信号处理程序 见说明 如果信号的处理动作是默认的或者忽略的则exec后不变,只有那些被设置过处理过程的信号才会被设置为默认处置
信号掩码 -
等待信号集 -
alarm设置的定时器 -
线程 见说明 fork之后只会将调用fork的线程复制过来,其他线程丢失并且不会调用线程清理函数
互斥量和条件变量 -

进程组、会话与作业控制

上一篇下一篇

猜你喜欢

热点阅读