程序与进程
内核中的进程结构
task_struct(进程表项和进程控制块)
- 位于
/usr/src/linux-headers-4.15.0-213-generic/include/linux/sched.h
C程序启动过程
进程终止方式
进程终止函数 atexit
小案例
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
// 定义进程终止函数
void term_fun1()
{
printf("first term function\n");
}
void term_fun2()
{
printf("second term function\n");
}
void term_fun3()
{
printf("third term function\n");
}
int main(int argc,char * argv[])
{
if(argc<0)
{
fprintf(stderr,"usage:%s file [exit|_exit|retrun\n",argv[0]);
exit(1);
}
// 向进程登记进程终止函数
atexit(term_fun1);
atexit(term_fun2);
atexit(term_fun3);
FILE *fp = fopen(argv[1],"w");
fprintf(fp,"hello iotek"); // 全缓存
if(!strcmp(argv[2],"exit"))
exit(0);
else if(!strcmp(argv[2],"_exit"))
_exit(0); // 标准C库函数
else if(!strcmp(argv[2],"retrurn"))
return 0;
else
{
fprintf(stderr,"usage %s file [exit|_exit|retrun]\n",argv[0]);
}
return 0;
}
系统调用的
_exit执行,不会调用终止函数也不会刷新缓存
- 终止函数以一种栈的方式,先登记的最后被调用
进程启动和退出
非局部跳转
进程资源限制
进程创建
fork
正文段就是代码段
- 全局变量和静态变量存储在虚拟内存中的数据段中,局部变量在栈中。
案例:父子进程操作变量
nt g_v = 30;
int main(void)
{
int a_v = 30;
static int s_v = 30;
printf("pid %d\n",getpid());
pid_t pid;
pid = fork();
if(pid==0)
{
printf("Son before~ g_v=%d a_v=%d s_v%d\n",g_v,a_v,s_v);
g_v = 50;
a_v =50;
s_v = 50;
printf("Son after~ g_v=%p a_v=%p s_v%p\n",&g_v,&a_v,&s_v);
}
else if(pid>0)
{
printf("Parent before~ g_v=%d a_v=%d s_v%d\n",g_v,a_v,s_v);
g_v = 40;
a_v = 40;
s_v = 40;
printf("Parent after~ g_v=%p a_v=%p s_v%p\n",&g_v,&a_v,&s_v);
}
else
perror("fork error\n");