命令ps查看进程,pstree查看所有进程
命令top相当于任务管理器,动态变化进程的信息 父子孤尸:
父子进程:父进程可以有多个子进程,一个子进程只能有一个父进程
调度进程:PID =0 孤儿进程:父进程先于子进程结束(一种状态),(老版本)操作系统会为子进程找父进程,即
被init进程收养,init进程又被称为孤儿院进程,(新版本)随机进程收养 僵尸进程:父子进程同时执行,子进程先于父进程结束,子进程还有部分资源在
内存中占用,父进程负责释放,但由于某种原因,父进程并没有回收子进程的终止状态,这时子进程处于僵尸
状态,被称为僵尸进程 进程标识:
当前进程:PID
当前进程父进程:PPID 1.实际用户id(real user id):当前进程的实际调用用户的id
2.有效用户id(effective user id):文件的set_user_id位被关闭,和实际用户id一样;
set_uesr_id开启,为文件拥有者的id,
3.保存的设置用户id(saved set-user-id):程序运行时有效用户id的副本
//各种ID #include进程的创建:#include int main(void) { printf(" 当前进程ID:%dn",getpid()); printf(" 父进程ID:%dn",getppid()); printf(" 实际用户ID:%dn",getuid()); printf(" 用户组ID:%dn",getgid()); printf(" 有效用户ID:%dn",geteuid()); printf("有效用户组ID:%dn",getegid()); } tarena: 当前进程ID:88304 父进程ID:76181 实际用户ID:1000 用户组ID:1000 有效用户ID:1000 有效用户组ID:1000 root:su root 命令进入root用户,在root用户编译文件idroot执行 当前进程ID:88339 父进程ID:88321 实际用户ID:0 用户组ID:0 有效用户ID:0 有效用户组ID:0 当设置用户ID:在tarena用户编译 当前进程ID:88375 父进程ID:88343 实际用户ID:1000 用户组ID:1000 有效用户ID:0 有效用户组ID:1000
fork();
一次创建,两次返回:返回值为子进程的PID和0; 子进程是父进程的不完全副本,除了会复制父进程的数据区、BSS区
、堆区、栈区、参数和环境变量外,包括输入输出缓冲区(内容也会)也会进行复制。
(代码区共享) fork()函数返回后,系统内核会将父进程维护的文件描述符表也复制到
子进程的进程表项中,但并不复制文件表象。
父进程和子进程共哟个一个文件表象,子进程改变读写位置,父进程也随着改变 setbuf(setout,NULL);//关闭输出缓冲区
#include#include #include int global = 10; int main(void) { int local = 20; int * heap = (int*)malloc(sizeof(int)); *heap =30; printf("进程:%d %p:%d %p:%d %p:%dn",getpid(),&global,global,&local,local,heap,*heap); pid_t pid = fork(); if(pid == -1) { perror("fork"); return -1; } //子进程 if(pid == 0) { printf("进程:%d %p:%d %p:%d %p:%dn",getpid(),&global,++global,&local,++local,heap,++*heap); return 0; } //父进程 sleep(1); printf("进程:%d %p:%d %p:%d %p:%dn",getpid(),&global,global,&local,local,heap,*heap); return 0; } 进程:90412 0x601068:10 0x7ffd2f3b0528:20 0xe66010:30 进程:90413 0x601068:11 0x7ffd2f3b0528:21 0xe66010:31 进程:90412 0x601068:10 0x7ffd2f3b0528:20 0xe66010:30
//子进程复制父进程的文件描述符表 #include进程的终止:正常终止#include #include #include int main() { //父进程打开文件 int fd = open("./shared.txt",O_WRONLY | O_CREAT | O_TRUNC,0777); if(fd == -1) { perror("open"); return -1; } //父进程写入hello word char * a ="hello world!"; if(write(fd,a,strlen(a)) == -1) { perror("write"); return -1; } //进入子进程 pid_t pid = fork(); if(pid == -1) { perror("fork"); return -1; } //子进程改变文件读写位置 if(pid == 0) { if(lseek(fd,-6,SEEK_END) ==-1) { perror("lseek"); return -1; } close(fd); return 0; } //父进程写入linux sleep(1); char* b ="linux"; if(write(fd,b,strlen(b)) == -1) { perror("write"); return -1; } close(fd); return 0; } 睡眠一秒钟文件内容为hello linux!
1、从main函数中返回可令进程终止 return 0;
2、调用exit函数令进程终止 exit(0);//不返回 终止进程前做的事:
A、调用实现通过atexit或on_exit函数注册的退出处理函数;
B、冲刷并关闭所有仍处于打开状态的标准I/O流;
C、删除所有通过tmpfile函数创建的临时文件;
D、_exit(status);
3、调用_exit/EXIT令进程终止 终止进程前做的事:
A、关闭所有仍处于打开状态的文件描述符
B、将调用进程的所有子进程托付给init进程收养
C、向调用进程的父进程发送SIGCHLD(17)信号
D、令调用进程终止运行,将status的低八位作为退出码保存在其终止状态中
异常终止:
1、当进程执行了某些在系统看起来具有危险性的操作,或系统本身发生了
某种故障或意外,内核会向相关进程发送特定的信号,如果进程无意针对
收到的信号采取补救措施,那么内核将按照缺省方式将进程杀死并视情节
生成和核心转储文件(core)以备事后分析,俗称吐核
SIGILL(4):进程试图执行非法指令
SIGBUS(7):硬件或对齐错误
SIGFPE(8):浮点异常
SIGSEG(11):无效内存访问
SIGPWR(30):系统供电不足
2、人为触发信号
SIGINT(2):Ctrl+C
SIGQUIT(3):Ctrl+
SIGKILL(9):不能被捕获或忽略的进程终止信号
SIGTERM(15):可以被捕获或忽略的进程终止信号
3、向进程自己发送信号
#include
void abort(void);
功能:向调用进程发送SIGABRT(6)信号,该信号默认情况下可使进程
结束,无参数,不返回!



