进程控制:
父子进程之间采用“读时共享、写时复制”原则
父子进程在刚fork之后,有哪些异同点?
相同处:全局变量、data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式
不同处:1.进程ID 2.fork返回值 3.父进程ID 4.进程运行时间 5.闹钟(定时器) 6.未决信号集
父子进程相同处和不同处是在只读情况下成立,牵扯到写时各自都有独立的一份
父子进程共享:
a.文件描述符(打开文件的结构体)
b.mmap建立的映射区(进程间通讯)
fork之后父子进程先后执行顺序取决于内核使用的调度算法。
1.fork函数--是一个循环创建子进程的架构
返回值有2个:一个进程-->变成两个进程-->各自对fork做返回
1.父进程返回子进程的pid(非负整数>0)
2.子进程返回0
示例:fork.c
--------------------start--------------------------- #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { pid_t pid; printf("null.null.null.null.null. "); pid = fork(); if(pid == -1) { perror("fork error."); exit(1); } else if(pid == 0) { printf("I am child, pid=%u, ppid=%u ", getpid(), getppid()); } else { printf("I am parent, pid=%u, ppid=%u ", getpid(), getppid()); } printf("YYYYYYYYYYYYYYYYYYYYY "); } ------------------------end---------------------------------
示例:创建5个子进程 fork2.c
--------------------start--------------------------- #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { int i; pid_t pid; printf("null.null.null.null.null. "); for(i = 0; i < 5; i++) { pid = fork(); if(pid == 0) { break; } } sleep(i); if(i < 5) { printf("I am child,ith=%d, pid=%u, ppid=%u ", i, getpid(), getppid()); } else { printf("I am parent, pid=%u, ppid=%u ", getpid(), getppid()); } printf("YYYYYYYYYYYYYYYYYYYYY "); return 0; } ------------------------end---------------------------------
2. getpid函数--获取当前进程id
getppid函数--获取父进程id
3. getuid函数
uid_t getuid(void); 获取当前进程实际用户ID
geteuid函数
uid_t geteuid(void); 获取当前进程有效用户ID
4. getgid函数
gid_t getgid(void); 获取当前进程使用用户组ID
getegid函数
gid_t getegid(void); 获取当前进程有效用户组ID
5. gdb调试fork,只能跟踪一个进程,默认跟踪父进程
通过指令设置gdb调试工具:
set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程
set follow-fork-mode parent 设置跟踪父进程
该指令一定要在fork之前设置
6.exec函数执行指令