进程环境
命令行参数(main)
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* @brief 命令行及其传参
*
* @param argc :(argument count) 参数的个数
* @param argv :(argument vector) 参数的字符串数组
* @return int
*/
// ./main_args_demo xixi hehe haha
int main(int argc, char* argv[]) {
// argc = 3
// argv = {"./main_args_demo", "xixi", "hehe", "haha"}
printf("argc = %d\n", argc);
for (int i = 0; argv[i] != NULL; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
环境变量
每个程序都会收到一张环境表
.
全局变量保存了该指针数组的地址:
c
extern char** environ;
表结构:
shell
key=value
getenv/setenv/unsetenv
char *getenv(const char *name);
通过key,获取valueint setenv(const char *name, const char *value, int overwrite);
设置环境变量int unsetenv(const char *name);
通过key,取消环境变量的设置
Example:
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// extern char** environ
// getenv
// setenv
// 声明
extern char** environ;
int main(int argc, char* argv[]) {
// for (int i = 0; environ[i] != NULL; i++) {
// printf("%s\n", environ[i]);
// }
char* shell = getenv("SHELL");
printf("shell = %s\n", shell);
char* home = getenv("HOME");
printf("home = %s\n", home);
// xixi=hehe
setenv("xixi", "hehe", 1);
setenv("xixi", "haha", 1);
char* hehe = getenv("xixi");
printf("home = %s\n", hehe);
return 0;
}
getrlimit/setrlimit函数
每个进程都有一组资源限制, 可以通过getrlimit/setrlimit函数查询和更改 ulimit
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
c
struct rlimit {
rlim_t rlim_cur; /* Soft limit */
rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */
};
参数resource
- RLIMIT_AS //进程的最大虚内存空间,字节为单位。
- RLIMIT_CORE //内核转存文件的最大长度。
- RLIMIT_CPU //最大允许的CPU使用时间,秒为单位。当进程达到软限制,内核将给其发送SIGXCPU信号,这一信号的默认行为是终止进程的执行。然而,可以捕捉信号,处理句柄可将控制返回给主程序。如果进程继续耗费CPU时间,核心会以每秒一次的频率给其发送SIGXCPU信号,直到达到硬限制,那时将给进程发送 SIGKILL信号终止其执行。
- RLIMIT_DATA //进程数据段的最大值。
- RLIMIT_FSIZE //进程可建立的文件的最大长度。如果进程试图超出这一限制时,核心会给其发送SIGXFSZ信号,默认情况下将终止进程的执行。
- RLIMIT_LOCKS //进程可建立的锁和租赁的最大值。
- RLIMIT_MEMLOCK //进程可锁定在内存中的最大数据量,字节为单位。
- RLIMIT_MSGQUEUE //进程可为POSIX消息队列分配的最大字节数。
- RLIMIT_NICE //进程可通过setpriority() 或 nice()调用设置的最大完美值。
- RLIMIT_NOFILE //指定比进程可打开的最大文件描述词大一的值,超出此值,将会产生EMFILE错误。
- RLIMIT_NPROC //用户可拥有的最大进程数。
- RLIMIT_RTPRIO //进程可通过sched_setscheduler 和 sched_setparam设置的最大实时优先级。
- RLIMIT_SIGPENDING //用户可拥有的最大挂起信号数。
- RLIMIT_STACK //最大的进程堆栈,以字节为单位。
命令程序ulimit
shell
$ ulimit --help
-a:显示目前资源限制的设定;
-c <core文件上限>:设定core文件的最大值,单位为区块;
-d <数据节区大小>:程序数据节区的最大值,单位为KB;
-f <文件大小>:shell所能建立的最大文件,单位为区块;
-H:设定资源的硬性限制,也就是管理员所设下的限制;
-m <内存大小>:指定可使用内存的上限,单位为KB;
-n <文件数目>:指定同一时间最多可开启的文件数;
-p <缓冲区大小>:指定管道缓冲区的大小,单位512字节;
-s <堆叠大小>:指定堆叠的上限,单位为KB;
-S:设定资源的弹性限制;
-t <CPU时间>:指定CPU使用时间的上限,单位为秒;
-u <程序数目>:用户最多可开启的程序数目;
-v <虚拟内存大小>:指定可使用的虚拟内存上限,单位为KB。
$ ulimit -a
core file size (blocks, -c) 0 #core文件的最大值为100 blocks。
data seg size (kbytes, -d) unlimited #进程的数据段可以任意大。
scheduling priority (-e) 0
file size (blocks, -f) unlimited #文件可以任意大。
pending signals (-i) 98304 #最多有98304个待处理的信号。
max locked memory (kbytes, -l) 32 #一个任务锁住的物理内存的最大值为32KB。
max memory size (kbytes, -m) unlimited #一个任务的常驻物理内存的最大值。
open files (-n) 1024 #一个任务最多可以同时打开1024的文件。
pipe size (512 bytes, -p) 8 #管道的最大空间为4096字节。
POSIX message queues (bytes, -q) 819200 #POSIX的消息队列的最大值为819200字节。
real-time priority (-r) 0
stack size (kbytes, -s) 10240 #进程的栈的最大值为10240字节。
cpu time (seconds, -t) unlimited #进程使用的CPU时间。
max user processes (-u) 98304 #当前用户同时打开的进程(包括线程)的最大个数为98304。
virtual memory (kbytes, -v) unlimited #没有限制进程的最大地址空间。
file locks (-x) unlimited #所能锁住的文件的最大个数没有限制。
ulimit_demo.c
c
// #include "apue.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>
#define doit(name) pr_limits(#name, name)
static void pr_limits(char*, int);
int main(void) {
#ifdef RLIMIT_AS
doit(RLIMIT_AS);
#endif
doit(RLIMIT_CORE);
doit(RLIMIT_CPU);
doit(RLIMIT_DATA);
doit(RLIMIT_FSIZE);
#ifdef RLIMIT_MEMLOCK
doit(RLIMIT_MEMLOCK);
#endif
#ifdef RLIMIT_MSGQUEUE
doit(RLIMIT_MSGQUEUE);
#endif
#ifdef RLIMIT_NICE
doit(RLIMIT_NICE);
#endif
doit(RLIMIT_NOFILE);
#ifdef RLIMIT_NPROC
doit(RLIMIT_NPROC);
#endif
#ifdef RLIMIT_NPTS
doit(RLIMIT_NPTS);
#endif
#ifdef RLIMIT_RSS
doit(RLIMIT_RSS);
#endif
#ifdef RLIMIT_SBSIZE
doit(RLIMIT_SBSIZE);
#endif
#ifdef RLIMIT_SIGPENDING
doit(RLIMIT_SIGPENDING);
#endif
doit(RLIMIT_STACK);
#ifdef RLIMIT_SWAP
doit(RLIMIT_SWAP);
#endif
#ifdef RLIMIT_VMEM
doit(RLIMIT_VMEM);
#endif
exit(0);
}
static void pr_limits(char* name, int resource) {
struct rlimit limit;
unsigned long long lim;
if (getrlimit(resource, &limit) < 0) {
printf("getrlimit error for %s", name);
return;
}
printf("%-14s ", name);
if (limit.rlim_cur == RLIM_INFINITY) {
printf("(infinite) ");
} else {
lim = limit.rlim_cur;
printf("%10lld ", lim);
}
if (limit.rlim_max == RLIM_INFINITY) {
printf("(infinite)");
} else {
lim = limit.rlim_max;
printf("%10lld", lim);
}
putchar((int)'\n');
}
环境变量
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char** environ;
int main(int argc, char* argv[]) {
for (int i = 0; environ[i]; i++) {
printf("%s\n", environ[i]);
}
return 0;
}
相关函数
c
#include <stdlib.h>
char * getenv(const char *name); // 获取
int setenv(const char *name, const char *value, int overwrite); // 设置
int putenv(char *string); //
int unsetenv(const char *name); // unset