1. 简介
本章简要介绍了进程的运行环境,包括进程的启动、终止、命令行参数、环境参数和程序的空间布局、内存分配、进程资源限制等内容。
2. 函数原型
void exit(int status); void _exit(int status); void _Exit(int status); | _exit和_Exit立即进入内核终止进程,exit会做一些清理工作,比如标准IO库的清理关闭操作,调用终止处理程序等。 |
int atexit(void (*function)(void)); | 注册进程终止处理程序,调用顺序与注册顺序相反 |
void *malloc(size_t size); void free(void *ptr); | 动态内存分配和释放 |
void *alloca(size_t size); | 在函数的栈帧上分配存储空间,自动释放 |
char *getenv(const char *name); int setenv(const char *name, const char *value, int overwrite); int putenv(char *string); int unsetenv(const char *name); | 获取/设置/删除环境变量,putenv不会分配内存,因此慎用局部变量设置环境变量 |
int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val); | 相对于goto语句的局部跳转,这两个函数可实现非局部跳转 |
int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim); | 获取/设置进程的资源限制 |
3. 实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/resource.h>
void exit1()
{
printf("%s\n", __FUNCTION__);
}
void exit2()
{
printf("%s\n", __FUNCTION__);
}
void exit3()
{
printf("%s\n", __FUNCTION__);
}
extern char **environ;
static jmp_buf test_jmp;
void test_jmp1()
{
printf("test_jmp1\n");
//longjmp(test_jmp, 1);
}
void test_jmp2()
{
test_jmp1();
printf("test_jmp2\n");
longjmp(test_jmp, 2);
}
void test_jmp3()
{
test_jmp2();
printf("test_jmp3\n");
//longjmp(test_jmp, 3);
}
void test_jmp4()
{
int val = setjmp(test_jmp);
printf("setjmp: %d\n", val);
if (val != 0) {
return;
}
test_jmp3();
printf("test_jmp4\n");
}
#define TEST_RESOURCE(name) do { \
struct rlimit limit = {0}; \
if (getrlimit(name, &limit) == 0) { \
printf("%16s: ",#name); \
if (limit.rlim_cur == RLIM_INFINITY) { \
printf("unlimited\n"); \
} else { \
printf("%ld\n", limit.rlim_cur); \
} \
} else { \
printf("getrlimit erro\n"); \
} \
} while (0)
void put_env()
{
char test[] = "test=hello";
#if 0
// Cannot set string stored in stack area
putenv(test);
#else
setenv("test", "hello", 1);
#endif
}
int main(int argc, char *argv[])
{
printf("Hello world!");
atexit(exit3);
atexit(exit2);
atexit(exit1);
for (int i = 0; i < argc; i++) {
printf("argv[%d]: %s\n", i, argv[i]);
}
char **tmp = environ;
while (*tmp) {
printf("%x: %s\n", tmp, *tmp);
tmp++;
}
put_env();
char *test = getenv("test");
if (test) {
printf("%s\n", test);
}
test_jmp4();
// shell command: ulimit -a
TEST_RESOURCE(RLIMIT_AS);
TEST_RESOURCE(RLIMIT_CORE);
TEST_RESOURCE(RLIMIT_CPU);
TEST_RESOURCE(RLIMIT_FSIZE);
TEST_RESOURCE(RLIMIT_STACK);
TEST_RESOURCE(RLIMIT_MSGQUEUE);
TEST_RESOURCE(RLIMIT_NOFILE);
TEST_RESOURCE(RLIMIT_NPROC);
#if 1
exit(-1);
#else
//_exit(-1);
_Exit(-1);
#endif
return 0;
}
4. 小结
1. 理解进程的启动和终止及空间布局
2. 掌握内存分配、环境变量控制和进程资源相关函数使用