文章目录
7 进程环境
7.2 main函数
main函数的原型
int main(int argc, char *argv[]);
argc 命令行参数个数
argv 命令行参数数组,一般argv[0]就是可执行文件的名称
- C程序总是从main函数开始执行
7.3 进程终止
有8种方式使进程终止:
- 正常终止5种:
[1] 从main函数return
[2] 调用exit
[3] 调用_exit或_Exit
[4] 进程的最后一个线程return
[5] 进程的最后一个线程调用pthread_exit - 异常终止5种:
[6] 调用abort()
[7] 收到一个信号
[8] 进程中的最后一个线程对取消请求做出响应
7.3.1 exit函数
#include <stdlib.h> /* from IOS C */
void exit(int status);
void _Exit(int status);
#include <unistd.h> /* from POSIX.1 */
void _exit(int status);
区别是exit会先关闭所有打开的流,并冲刷缓冲区
/* 7.3.1-1.c */
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("test ouput"); /* 行缓冲,这里不加换行符来测试 */
exit(0);
// _exit(0);
// _Exit(0);
}
一次使用这三个函数来退出,结果如下:
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ make
gcc -Wall 7.3.1-1.c -o 7.3.1-1.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.3.1-1.out
test ouputmyx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ make
gcc -Wall 7.3.1-1.c -o 7.3.1-1.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.3.1-1.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ make
gcc -Wall 7.3.1-1.c -o 7.3.1-1.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.3.1-1.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$
使用exit从main退出, return 0和exit 0一样
我们知道如果exit(0), 那么返回值就是0, 如果忘记写exit会返回什么?
测试c98是返回最后一行有返回值的语句的返回值
c99之后就是默认返回0
/* 7.3.1-2.c */
#include <stdio.h>
int main()
{
printf("hello world\n"); /* printf返回输出的字符数 */
int i = 25;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -std=c89 7.3.1-2.c
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./a.out
hello world
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ echo $?
12
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -std=c99 7.3.1-2.c
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./a.out
hello world
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ echo $?
0
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -std=c17 7.3.1-2.c
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./a.out
hello world
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ echo $?
0
7.3.2 atexit函数
#include <stdlib.h>
int atexit(void (*func)(void));
返回0 ok,非0不ok
- 一个进程可以注册最少32个函数, 实际上要大很多, 可以用sysconf(_SC_ATEXIT_MAX)查看,例如我的机器上2147483647
- 可以重复注册同一个函数, 而且也会重复执行
/* 7.3.1-3.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int n = 0;
void func_0()
{
n++;
printf("n = %d\n", n);
printf("%s\n", __FUNCTION__);
}
void func_1()
{
printf("%s\n", __FUNCTION__);
}
int main()
{
for (int i = 0; i < 3; i++)
{
if (atexit(func_0) < 0)
{
perror("atexit err");
}
}
if (atexit(func_1) < 0)
{
perror("atexit err");
}
printf("max atexit :%ld\n", sysconf(_SC_ATEXIT_MAX));
printf("output");
exit(0);
}
max atexit :2147483647
outputfunc_1
n = 1
func_0
n = 2
func_0
n = 3
func_0
exit会先按注册相反的顺序执行注册的函数,再关闭流,再调用_Exit(或_exit)
7.4 命令行参数
IOS C和POSIX.1保证argv[argc]不是空指针
/* 7.4-1.c */
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i++)
{
printf("%d -> %s\n", i, argv[i]);
}
for (int i = 0; argv[i] != NULL; i++)
{
printf("%d -> %s\n", i, argv[i]);
}
printf("%d\n", argv[argc] == NULL);
printf("%d\n", argv[argc+1] == NULL);
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.4-1.out argc1 TEST foo
0 -> ./7.4-1.out
1 -> argc1
2 -> TEST
3 -> foo
0 -> ./7.4-1.out
1 -> argc1
2 -> TEST
3 -> foo
1
0
7.5 环境变量列表
有一个全局变量指针(environ),指向一个列表,列表里是name=value形式的环境变量字符串
#include <stdio.h>
int main()
{
extern char **environ;
int i = 0;
while(environ[i] != NULL)
{
printf("%d - > %s\n", i, environ[i]);
i++;
}
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.5-1.out
0 - > SHELL=/bin/bash
1 - > COLORTERM=truecolor
2 - > TERM_PROGRAM_VERSION=1.92.2
3 - > WSL_DISTRO_NAME=Ubuntu-24.04
4 - > NAME=DESKTOP-QHCLCNF
5 - > PWD=/home/myx/files/APUE/Chapter-07
6 - > LOGNAME=myx
7 - > VSCODE_GIT_ASKPASS_NODE=/home/myx/.vscode-server/bin/fee1edb8d6d72a0ddff41e5f71a671c23ed924b9/node
8 - > MOTD_SHOWN=update-motd
9 - > HOME=/home/myx
10 - > LANG=C.UTF-8
11 - > WSL_INTEROP=/run/WSL/15_interop
12 - > LS_COLORS=rs=0:di=01;34:ln=01; /* 为了简洁省略 */
13 - > GIT_ASKPASS=/home/myx/.vscode-server/bin/fee1edb8d6d72a0ddff41e5f71a671c23ed924b9/extensions/git/dist/askpass.sh
14 - > VSCODE_GIT_ASKPASS_EXTRA_ARGS=
15 - > LESSCLOSE=/usr/bin/lesspipe %s %s
16 - > TERM=xterm-256color
17 - > LESSOPEN=| /usr/bin/lesspipe %s
18 - > USER=myx
19 - > VSCODE_GIT_IPC_HANDLE=/tmp/vscode-git-1f5d463cd5.sock
20 - > SHLVL=1
21 - > DEBUGINFOD_URLS=https://debuginfod.ubuntu.com
22 - > WSLENV=VSCODE_WSL_EXT_LOCATION/up
23 - > VSCODE_GIT_ASKPASS_MAIN=/home/myx/.vscode-server/bin/fee1edb8d6d72a0ddff41e5f71a671c23ed924b9/extensions/git/dist/askpass-main.js
24 - > XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
25 - > PATH=/home/ /* 为了简洁省略 */
26 - > HOSTTYPE=x86_64
27 - > TERM_PROGRAM=vscode
28 - > VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-32cfe76c-e457-4cfc-9f32-050b1d8644c6.sock
29 - > _=./7.5-1.out
30 - > OLDPWD=/home/myx/files/APUE
7.6 C语言典型内存布局
/* 7.6-1.c */
int global_i = 1000;
int global_no_i;
int main()
{
int local_i = 2000;
int local_no_i;
int *p = malloc(sizeof(int));
printf("global_i : %p\n", &global_i);
printf("global_no_i : %p\n", &global_no_i);
printf("local_i : %p\n", &local_i);
printf("local_no_i : %p\n", &local_no_i);
printf("p : %p\n", p);
while(1)
{
sleep(1);
}
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ size 7.6-1.out
text data bss dec hex filename
1786 620 12 2418 972 7.6-1.out
- 代码段:只读、可复用
- 初始化数据段
- bss(block start by symbol)存放未初始化的全局变量和静态变量, 会在程序加载的时候进行初始化为0
其实这里存的什么呢?看size执行的bss对应的12,其实就是global_no_i这个名字, 带null结尾的C风格字符串 - 栈(stack)
- 堆(heap)
7.7 动态库
以之前这个程序为例子
/* 7.3.1-1.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("test ouput");
exit(0);
// _exit(0);
// _Exit(0);
}
使用静态库
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -static 7.3.1-1.c -o static.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ size static.out
text data bss dec hex filename
667862 23360 22440 713662 ae3be static.out
使用动态库
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc 7.3.1-1.c -o shared.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ size shared.out
text data bss dec hex filename
1466 608 8 2082 822 shared.out
明显使用静态连接得到的程序大的多
使用静态连接,lib可以放在内存中,多个程序均可使用,且更换lib也不用所有涉及程序全部重新编译
但是也可能带来一些运行时代价
怎么制作自己的库文件呢(linux下的.so .a windows下的.dll .lib)
只看linux下的,winodws的没用过
库的名字应该是 lib + name + .a / .so
使用的时候只需要用name就行
- 生成静态库
制作静态库 ar rcs libmylib.a mylib.o
对于ar的参数
选项 | 说明 |
---|---|
d | 从库中删除 |
p | 打印库中指定成员 |
r | 在库中添加新成员,如果已经存在则覆盖,否则添加在库的末尾 |
t | 显示库中成员文件清单 |
a | 在库中已经存在的成员后面添加一个新的成员 |
c | 创建一个库 |
i | 在库中已经存在的成员前面添加一个新的成员 |
s | 无论ar命令是否修改了库内存,均重新生成库符号表 |
x | 从库中提取一个指定成员文件,不指定则提取所有文件 |
-
生成动态库
gcc -fPIC -shared mylib.c -o libmylib.so -
使用lib
使用gcc -print-search-dirs可以查看gcc找lib会去哪些文件夹找
install: /usr/lib/gcc/x86_64-linux-gnu/13/
programs: =/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/
libraries: =/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/13/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/13/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/
要么把lib拷贝到这些目录中,要么收到指定查找目录
方法不止一种,这里仅尝试一种比较通用的
对于静态库,编译时 -Ldir_path -llib_name
对于动态库,编译时 -Wl,-rpath so_path, 用于运行时查找动态库
/* mylib.h */
#ifndef _MYLIB_H_
#define _MYLIB_H_
void myFunc();
#endif /* _MYLIB_H_ */
/* mylib.c */
#include <stdio.h>
void myFunc()
{
printf("use my lib\n");
}
/* main.c */
#include "mylib.h"
int main()
{
myFunc();
return 0;
}
/* Makefile */
objs = libmylib.a libmylib.so main_staic.out main_shared.out
all : ${objs}
.PHONY : all
libmylib.a : mylib.h mylib.c
gcc mylib.c -c -o mylib.o ; \
ar crs libmylib.a mylib.o
libmylib.so : mylib.h mylib.c
gcc -fPIC -shared mylib.c -o libmylib.so
main_staic.out : main.c libmylib.a
gcc main.c -o main_staic.out -L. -lmylib -static
main_shared.out : main.c libmylib.so
gcc main.c -o main_shared.out -Wl,-rpath . -L. -lmylib
clean :
rm -rf *.so *.a *.out *.o
.PHONY : all
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ make
gcc mylib.c -c -o mylib.o ; \
ar crs libmylib.a mylib.o
gcc -fPIC -shared mylib.c -o libmylib.so
gcc main.c -o main_staic.out -L. -lmylib -static
gcc main.c -o main_shared.out -Wl,-rpath . -L. -lmylib
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ ./main_staic.out
use my lib
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ ./main_shared.out
use my lib
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ size main_staic.out
text data bss dec hex filename
668346 23376 22472 714194 ae5d2 main_staic.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ size main_shared.out
text data bss dec hex filename
1373 632 8 2013 7dd main_shared.out
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ rm libmylib.so
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ ./main_staic.out
use my lib
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07/7.7$ ./main_shared.out
/* 这里把so文件删除了,使用动态库的程序找不到就会报错 */
./main_shared.out: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
7.8 内存申请
这里APUE介绍了其他的API,但是没遇到过先跳过
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t size);
void *realloc(void *ptr, size_t newsize);
/* 成功返回非NULL指针,失败返回NULL */
void *free(void *ptr);
- calloc申请的内存会初始化为0
- realloc,如果扩大了大小,新增部分不初始化为0,且位置可能发生变化,这种特性容易引入bug,所以很多公司禁止使用这个
vmalloc 申请的内存,逻辑连续,在w屋里内存上可能不连续
7.9 环境变量
环境变量的形式是一个字符串 name=value
可以使用getenv来获取name对应的value
#include <stdlib.h>
char *getenv(const char *name);
成功返回一个指针,找不到返回NULL
/* 7.9-1.c */
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *value1 = getenv("PWD");
printf("PWD=%s\n", value1);
char *value2 = getenv("NOEXIST");
printf("NOEXIST=%s\n", value2);
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.9-1.out
PWD=/home/myx/files/APUE/Chapter-07
NOEXIST=(null)
使用putenv添加环境变量
接收一个name=value形式的字符串,如果name已经存在则进行覆盖
#include <stdlib.h>
int putenv(char *str);
返回0 ok,非0不ok
/* 7.9-2.c */
#include <stdio.h>
#include <stdlib.h>
void print_environ_list()
{
extern char **environ;
for (int i = 0; environ[i] != NULL; i++)
{
printf("%s\n", environ[i]);
}
}
int main()
{
if (0 != putenv("MYTEST=mytest"))
{
perror("putenv err 1");
}
print_environ_list();
printf("===================================================\n");
if (0 != putenv("MYTEST=mytest1"))
{
perror("putenv err 2");
}
print_environ_list();
printf("===================================================\n");
if (0 != putenv("MYTEST"))
{
perror("putenv err 3");
}
print_environ_list();
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.9-2.out
SHELL=/bin/bash
/* 省略 */
_=./7.9-2.out
MYTEST=mytest
===================================================
SHELL=/bin/bash
/* 省略 */
_=./7.9-2.out
MYTEST=mytest1
===================================================
SHELL=/bin/bash
/* 省略 */
_=./7.9-2.out
man手册中说明了一种情况,就是传入没有=的字符串,不会报错,反而会把这个name对应的环境变量清除掉
The GNU C library implementation provides a nonstandard extension. If string does not include an equal sign:
putenv("NAME");
then the named variable is removed from the caller's environment.
还可以使用setenv来控制在添加环境变量时是否进行覆盖
#include <stdlib.h>
int setenv(const char *name, const char *value, int rewrite);
rewrite是1,如果name存在就覆盖
rewrite是0,如果name存在就不覆盖,但是也不返回错误
成功0,失败-1
清除环境变量
int unsetenv(const char *name);
如果name对应的环境变量不存在,返回成功
7.10 setjmp 和 longjmp
goto只能在函数内部跳转,要在函数间跳转可以使用setjmp和longjmp
#include <setjmp.h>
int setjmp(jmp_buf env);
直接调用返回0,从longjmp返回,则返回非0
void longjmp(jmp_buf env, int val);
这个env就是setjmp的那个,所以一般env应该是个全局变量
val就是setjmp的返回值
一个setjmp可以对应多个longjmp
/* 7.10-1.c */
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
void func2(int i)
{
if (i > 2)
{
longjmp(env, 2);
}
else
{
printf("%s %d\n", __FUNCTION__, i);
}
}
void func1(int i)
{
if (i < 4)
{
func2(i);
}
else if (i > 5)
{
longjmp(env, 1);
}
else
{
printf("%s %d\n", __FUNCTION__, i);
}
}
int main(int argc, char *argv[])
{
int iRet = 0;
if (0 != (iRet = setjmp(env)))
{
printf("err code %d\n", iRet);
return -1;
}
for (int i = 0; i < 10; i++)
{
func1(i);
}
return 0;
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.10-1.out
func2 0
func2 1
func2 2
err code 2
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$
longjmp对于变量的影响:
/* 7-10-2.c */
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
static jmp_buf buf;
static int staticGlobalVar;
int globalVar;
void f2()
{
longjmp(buf, 1);
}
void f1(int i, int j, int k, int l)
{
printf("in f1()\n");
printf("staticGlobalVar:%d globalVar:%d autoVar:%d regVal:%d volVar:%d staticLocalVar:%d\n",
staticGlobalVar, globalVar, i, j, k, l);
f2();
}
int main()
{
int autoVar;
register int regVal;
volatile int volVar;
static int staticLocalVar;
staticGlobalVar = 1;
globalVar = 2;
autoVar = 3;
regVal = 4;
volVar = 5;
staticLocalVar = 6;
if (setjmp(buf) != 0)
{
printf("after longjmp\n");
printf("staticGlobalVar:%d globalVar:%d autoVar:%d regVal:%d volVar:%d staticLocalVar:%d\n",
staticGlobalVar, globalVar, autoVar, regVal, volVar, staticLocalVar);
exit(0);
}
staticGlobalVar = 101;
globalVar = 102;
autoVar = 103;
regVal = 104;
volVar = 105;
staticLocalVar = 106;
f1(autoVar, regVal, volVar, staticLocalVar);
exit(0);
}
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -Wall 7.10-2.c -o 7.10-2.out -O3
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.10-2.out
in f1()
staticGlobalVar:101 globalVar:102 autoVar:103 regVal:104 volVar:105 staticLocalVar:106
after longjmp
staticGlobalVar:101 globalVar:102 autoVar:3 regVal:4 volVar:105 staticLocalVar:106
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -Wall 7.10-2.c -o 7.10-2.out -O2
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.10-2.out
in f1()
staticGlobalVar:101 globalVar:102 autoVar:103 regVal:104 volVar:105 staticLocalVar:106
after longjmp
staticGlobalVar:101 globalVar:102 autoVar:3 regVal:4 volVar:105 staticLocalVar:106
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -Wall 7.10-2.c -o 7.10-2.out -O1
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.10-2.out
in f1()
staticGlobalVar:101 globalVar:102 autoVar:103 regVal:104 volVar:105 staticLocalVar:106
after longjmp
staticGlobalVar:101 globalVar:102 autoVar:3 regVal:4 volVar:105 staticLocalVar:106
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ gcc -Wall 7.10-2.c -o 7.10-2.out -O0
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ ./7.10-2.out
in f1()
staticGlobalVar:101 globalVar:102 autoVar:103 regVal:104 volVar:105 staticLocalVar:106
after longjmp
staticGlobalVar:101 globalVar:102 autoVar:103 regVal:4 volVar:105 staticLocalVar:106
看起来:
- 全局变量不受jmp影响,包括局部静态变量
- volatile变量不受jmp影响
- register变量会被longjmp恢复成setjmp时保存的
- 栈上的自动变量,情况不可预知
7.11 getrlimit 和 setrlimit
每个进程都有一些资源上的限制
有挺多的,具体看man手册
也可以 cat /proc/pid/limits
可以使用这两函数进行查询和设置
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit *rlptr);
成功返回0,失败-1
其中
struct rlimit
{
rlim_t rlim_cur; /* 软限制:当前值 */
rlim_t rlim_max; /* 硬限制:最大值 */
};
普通进程可以在硬限制范围内调整软限制,也可以降低硬限制
但是只有root进程可以增大硬限制
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$ cat /proc/1/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 102030 102030 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 102030 102030 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
myx@DESKTOP-QHCLCNF:~/files/APUE/Chapter-07$