控制欲强?视奸?普通人那才叫视奸,您是皇帝,天下大事无一逃过您的耳目,您想看什么就看什么,臣怀疑他在朋友圈私养兵士,囤积枪甲,蓄意谋反,图谋皇位啊!
哈哈哈哈开个玩笑,这篇就主要讲讲Linux进程的控制吧~
fork( )
由于fork()之前也说过啦(从已存在进程中创建一个新进程:新进程为子进程,原进程为父进程),所以下面主要讲内核的操作,进程调用fork,当控制转移到内核中的fork代码后,内核做:
1.分配新的内存块和内核数据结构给子进程
2.将父进程部分数据结构内容拷贝至子进程
3.添加子进程到系统进程列表当中
4.fork返回,开始调度器调度
当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以 开始它们自己的旅程:
#include <unistd.h>
#include<stdio.h>
int main(void)
{
pid_t pid;
printf("Before: pid is %d\n", getpid());
if ((pid = fork()) == -1)
perror("fork()"), exit(1);
printf("After:pid is %d, fork return %d\n", getpid(), pid);
sleep(1);
return 0;
}
先来下个定义:
进程=内核的相关管理数据结构(task_struct + mm_struct + 页表)+ 代码和数据
已知fork函数的返回值是这样的:
子进程返回0
父进程返回子进程的pid
那为什么捏?
原因其实也很简单,爹得知道儿子名,杀掉他啊等待他啊,爹总要知道的(为了方便父进程对紫禁城进行标识,进而进行管理)
进程具有独立性就在于紫禁城代码数据和父进程共享,但因为写时拷贝又不影响父进程
fork常规用法
一个父进程希望复制自己,使父子进程同时执行不同的代码段(父进程等待客户端请求,生成子 进程来处理请求)
一个进程要执行一个不同的程序(子进程从fork返回后,调用exec函数)
fork调用失败原因
系统中有太多的进程
实际用户的进程数超过了限制
进程终止
终止是在做什么
进程终止就是在释放曾经的代码和数据所占据的空间,也是在释放内核数据结构(task_struct,当进程状态是Z就要释放对应PCB)
终止三种情况
先来看两段代码:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hello world!\n");
return 0;
}
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hello world!\n");
return 100;
}
只有返回值不一样对吧,对?取内容会发现也不一样:
echo是内建命令,打印的都是bash内部的变量数据
?:父进程bash获取到的最近一个紫禁城的退出码 (0:成功,!0:失败)
退出码存在意义:告诉关心方(父进程)任务完成如何
因为成功的退出码就是0,而!0有很多,所以不同!0值一方面表示失败,一方面还表示失败的原因
可以这样打印下错误信息:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
int errcode = 0;
for (errcode = 0; errcode <= 255; errcode++)
{
printf("%d:%s\n", errcode, strerror(errcode));
}
return 0;
}
那么父进程知道紫禁城退出码因为点撒捏?
因为:!要知道紫禁城退出情况,正常退出了嘛,错误了嘛,错哪了呀,,,
错误码可以自己设定:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int Div(int x, int y)
{
if (0 == y)
{
return -1;
}
else
{
return x / y;
}
}
int main()
{
printf("%d\n",Div(-1,1));
return 0;
}
但是这样没法判断是y==0导致返回错误码-1,还是本来的计算结果就是-1
所以可以这样改:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
//自定义枚举常量
enum
{
Success = 0,
Div_Zero,
Mod_Zero,
};
int exit_code = Success;
int Div(int x, int y)
{
if (0 == y)
{
exit_code = Div_Zero;
return -1;
}
else
{
return x / y;
}
}
int main()
{
printf("%d\n", Div(-1, 1));
return exit_code;
}
还可以接着写接口补充错误信息:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
//自定义枚举常量
enum
{
Success = 0,
Div_Zero,
Mod_Zero,
};
int exit_c