进程基础

2017-09-21  本文已影响0人  wayyyy
main函数
int main(int argc, char **argv)

C程序一般是从main函数开始执行,当内核执行C程序时,在调用main函数前会先调用一个特殊的启动例程,可执行程序文件将此启动例程指定为程序的起始地址(由链接器设定),启动例程从内核取得命令行参数和环境变量,为调用main函数做好准备。

C程序的存储空间布局
C程序的内存布局.png

C程序一直由下列几部分组成:

存放在磁盘上的只有正文段和初始化数据段。(size命令可以查看)

进程环境变量
环境表.png

每个程序都会有一张环境表,全局变量environ包括该指针数组的地址。环境表通常放在进程存储的顶部

extern char **environ;

环境字符串形式: name=value

#include <stdlib.h>

int putenv(char *str)
    函数返回值:成功返回0,出错返回非0

int setenv(const char* name, const char* value, int rewrite);
    函数返回值:成功返回0,出错返回非0

int unsetenv(const char* name);
    函数返回值:成功返回0,出错返回非0
进程标识

每一个进程都有一个非负整型pid_t表示的唯一进程ID。ID为0通常是调度进程,ID为1通常是 init进程,在自举过程中,此进程在自举内核后启动一个UNIX系统。

#include <unistd.h>

pid_t getpid()
    返回值:调用进程的进程ID
pid_t getppid()
    返回值:调用进程的父进程ID

uid_t getuid()
    返回值:调用进程的实际用户ID
uid_t getuid()
    返回值:调用进程的有效用户ID

gid_t getgid()
    返回值:调用进程的实际组ID
gid_t getegid()
    返回值:调用进程的有效组ID
进程创建
#include <unistd.h>

pid_t fork(void)
    返回值:子进程返回0,父进程返回子进程ID,若出错,返回-1。

子进程是父进程的副本,子进程获得父进程的数据空间,堆和栈的副本。父子进程共享正文段。

进程终止

3个函数用于正常终止一个程序:

_exit和_Exit立即进入内核,_exit和_Exit其目的是为进程提供一个无需运行终止处理程序或信号处理程序而终止的方法。它们并不冲洗标准I/O流 。

exit则先执行一些清理处理(典型的比如执行标准I/O库的清理关闭操作,对于所有的流调用fclose函数)

进程可以注册"终止处理函数",exit调用这些函数与他们注册时的顺序相反,同一函数若注册多次,也会被调用多次。

C程序如何清理和终止.jpg
回收进程资源

当一个进程正常或异常终止时,内核就向其父进程发送 SIGCHLD信号,父进程可以选择忽略(默认做法),也可以提供一个信号处理函数。

函数exec

在上面我们提到了fork的用法2:创建后调用exec以执行另一个程序

#include <unistd.h>

int execl(const char *pathname, const char* arg0, ... /* (char*)0 */);

int execv(const char* pathname, char*const argv[]);

int execle(const char* filename, const char* arg0, ... /* (char*)0 */)

int execve(const char* pathname, char* const argv[], char* const envp[]);

int execlp(const char* filename, const char* arg0, ... /* (char*)0 */)

int execvp(const char* filename, char* const argv[]);

int fexecve(int fd, char* const argv[], char* const envp[]);

    返回值:若出错,返回-1。若成功,不返回
7个exec.jpg
进程资源限制

每个进程都有一组资源限制,其中可以用以下函数查询和更改。

#include <sys/resource>

struct rlimit 
{
    rlim_t rlim_cur;    // soft limit
    rlim_t rlim_max;    // hard limit
};

int getrlimit(int resource, struct rlimit* rlptr);
    返回值:成功返回0,错误返回非0

int setrlimit(int resource, const struct rlimit* rlptr)
    返回值:成功返回0,错误返回非0

在更改资源限制时,必须遵循下列3条原则:

  1. 任何一个进程都可以提升软限制值,但软限制值必须小于或等于硬限制值。
  2. 任何一个进程都可以降低硬限制值,但硬限制值必须大于或等于软限制值。
  3. 只有超级用户进程可以提高硬限制值。

参数resource取下列值:

限制 作用
RLIMIT_NOFILE 每个进程能打开的做多文件数
RLIMIT_FSIZE 可以创建文件的最大字节长度
RLIMIT_NICE 影响进程调度优先级nice值可设置的最大值
RLIMIT_CORE core文件的最大字节数,值为0则不会创建core文件
RLIMIT_STACK 栈的最大字节长度
进程组

每个进程除了有一进程ID之外,还属于一个进程组,同一进程组中的各进程接收来自同一终端的各种信号。

上一篇 下一篇

猜你喜欢

热点阅读