- 问1. 什么是程序,什么是进程,有什么区别?
程序:静态
进程:动态;程序进行的过程
- 问2. 如何查看系统中有哪些进程?
ps 指令查看 ps -aux
top 观察进程;CPU占用率
grep 过滤 :|管道
- 问3. 什么是进程标识符?
init 系统初始化 pid = 1
swapper 交换进程 0
- 问4. 什么叫父进程,什么叫子进程?
getpid() 获取本进程的id号
getpid() 获取父进程的id号
- 问5. C程序的存储空间是如何分配?
高地址:运行环境;环境变量
栈:供主函数调用的内存,例:子函数
堆:开辟生成的内存;例:melloc出来的内存
未初始化 据 bss段
已初始化数据
低地址:正文;例:while(1);
1.创建一个进程fork()
pid_t fork(void)
fork函数调用成功,返回两次 返回值为0,代表当前进程是子进程 返回值非负数,代表当前进程为父进程 调用失败,返回-1
每个进程都有对应的存储空间
新Unix内核:子进程write的时候拷贝
旧Unix内核:全部拷贝父进程的数据 (参考demo7)
目的:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int data = 10;
printf("father: id=%d\n",getpid());
pid = fork();
if(pid > 0)
{
printf("this is father print, pid = %d\n",getpid());
}
else if(pid == 0){
printf("this is child print,child pid = %d\n",getpid());
data = data+100;
}
printf("data=%d\n",data);
return 0;
}
vfork函数 与fork有什么区别
- 关键区别一: vfork 直接使用父进程存储空间,不拷贝。
- 关键区别二: vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行(fork创建的进程使用呢wait也可达到此效果)。
2.进程退出
正常退出
- Main函数调用return
- 进程调用exit(),标准c库
- 进程调用_exit()或者_Exit(),属于系统调用
补充: 进程最后一个线程返回 最后一个线程调用pthread_exit
异常退出
- 调用abort
- 当进程收到某些信号时,如ctrl+C
- 最后一个线程对取消(cancellation)请求做出响应
void exit(int status);
void _exit(int status);
void _Exit(int status);
3.父进程等待子进程退出:
- 父进程收集子进程退出码(exit状态码)
- 如果子进程退出码不被收集,僵尸进程
- wait(*status);回收子进程退出码,()内为退出码存放位置,wait返回值是父进程进程pid
- WEXITSTATUST()解析退出码,解析后才能printf();
- 缺点:当所有子进程还在运行时,wait()阻塞,即父进程要等待子进程exit才可执行
pid_t wait(int *wstatus);
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid > 0)
{
wait(&status);
waitpid(pid,&status,WNOHANG);
printf("child quit, child status = %d\n",WEXITSTATUS(status));
while(1){
printf("cnt=%d\n",cnt);
printf("this is father print, pid = %d\n",getpid());
sleep(1);
}
}
else if(pid == 0){
while(1){
printf("this is chilid print, pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}
4.exec族函数
参考博文:linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)_云英的博客-CSDN博客_linux execl函数
perror("why") 查看exec调用失败原因
whereis ls 查看ls的路径
execl 只能通过绝对路径路径
execlp 通过环境变量找到路径
注意:
echo $PATH 查看环境变量
export PATH=$PATH:路径 将该路径添加为环境变量
5.system()函数
参考博文:linux system函数详解 - 南哥的天下 - 博客园
类似于exec族函数,system()源码中是调用exec族函数
区别:execl 会返回到源程序,system不会(直接退出程序)
system()函数的返回值如下:
成功,则返回进程的状态值; 当sh不能执行时,返回127; 失败返回-1;
6.popen()可以保存运行结果 返回是流FILE
参考博文:linux下popen的使用心得_libinbin_1014的博客-CSDN博客