1,pcb:进程控制块结构体:/usr/src/linux-headers-4.15.0-29/include/linux/sched.h
进程id:系统中每个进程有唯一的id,在c语言中用pid_t类型表示,是个非负整数。
进程状态:就绪,运行,挂起,停止等状态
描述虚拟地址空间的信息
描述控制终端的信息
进程执行时的当前工作目录(current working directory)
umask掩码
文件描述符表,包含很多指向file结构体的指针
和信号相关的信息
用户id和组id
会话(session)和进程组
进程可以使用的资源上限(Resource Limit)
用【ulimit -a】查看:
ys@ys:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7743 max locked memory (kbytes, -l) 16384 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7743 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
2,环境变量
查看所有的环境变量:env
环境写法:等号前后没有空格
KEY=VALUE
常用的环境变量:
- PATH:可执行文件的搜索路径。比如可以直接敲ls,那是因为ls的可执行文件在环境变量PATH里,所以系统找得到。但是比如a.out执行文件,就不能直接敲a.out,因为a.out不在PATH里。
- SHELL:当前使用的shell程序,通常是:/bin/bash
- TERM:当前使用的终端类型,如果是图像界面的话,一般为:xterm-256color
- LANG:当前的语言和字符编码,一般为:en_US.UTF-8
- HOME:当前用户所在的绝对路径。
获取环境变量:getenv
#include <stdlib.h>
char *getenv(const char *name);
返回值:
成功:返回指针
失败:返回NULL
设置环境变量:setenv
#include <stdlib.h>
int setenv(const char *name, const char *value, int overwrite);
删除环境变量:unsetenv
#include <stdlib.h>
int unsetenv(const char *name);
设置环境变量和删除环境变量一般不用系统函数,而是编辑【~/.bashrc】文件。
使用【exprot key=value】。
3,进程概念
创建进程:fork
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
- 返回值
- 失败:-1
- 成功:返回2次
- 父进程中返回:子进程的ID
- 子进程返回:0
获得当前进程自己id:getpid
获得当前进程的父进程的id:getppid
ss
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
理解fork的小例子:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
//char* val = getenv("HOME");
printf("begin...\n");
pid_t pid = fork();
printf("end...\n");
}
执行结果:
ys@ys:~/test$ ./en
begin...
end...
ys@ys:~/test$ end...
从执行结果发下:
1,【begin】被打印出1次;【end】被打印出2次。
2,第二个【end】跑到了shell的后面。
分析:
- 从执行结果1可以看出来,fork后,从1个进程,又分出了一个子进程。并且子进程不是从程序的开头开始执行,而是从fork后面开始执行,这个理解至关重要。
- 执行结果2现象的解释,根本原因是父进程比子进程先执行结束了,导致了子进程成为了孤儿进程。最开始shell进程把执行权交给程序,也就是父进程,当父进程结束后,shell又接管终端,可是这个时间点,子进程还没结束,子进程的打印语句就把【end】打印到了shell后面。
下面的例子可以了解,getpid和getppid的用法:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
//char* val = getenv("HOME");
printf("begin...\n");
pid_t pid = fork();
//child process
if(pid == 0){
printf("child: pid=%d, ppid=%d\n", getpid(), getppid());
}
//parent proces
else if(pid > 0){
printf("parent: pid=%d, child id:%d\n", getpid(), pid);
sleep(1);//为了让子进程先结束
}
printf("end...\n");
}
查看进程的命名:ps
- 选项a:显示更多信息
- 选项u:显示用户信息
- 选项x:和选项a一起使用
- 选项j:能看到父进程
ys@ys:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 159928 7536 ? Ss 13:53 0:02 /sbin/init spla
root 2 0.0 0.0 0 0 ? S 13:53 0:00 [kthreadd]
ys 4029 0.0 0.0 4508 812 pts/0 S+ 16:30 0:00 ./en
ys 4030 0.0 0.0 4508 80 pts/0 S+ 16:30 0:00 ./en
ys 4043 0.1 0.2 29560 4936 pts/1 Ss 16:30 0:00 bash
ys 4051 0.0 0.1 44472 3700 pts/1 R+