湖南平台网站建设企业,如何查看一个网站的域名解析,网站简繁体转换js,WordPress修改分类id1.进程创建
1.1.再谈fork
在linux中fork函数时非常重要的函数#xff0c;它从已存在进程中创建一个新进程。新进程为子进程#xff0c;而原进程为父进程。
#include unistd.h
pid_t fork(void);//pid_t为整形
返回值#xff1a;子进程中的fork()返回0#xff…1.进程创建
1.1.再谈fork
在linux中fork函数时非常重要的函数它从已存在进程中创建一个新进程。新进程为子进程而原进程为父进程。
#include unistd.h
pid_t fork(void);//pid_t为整形
返回值子进程中的fork()返回0父进程中的fork()返回子进程的id (pid)出错时返回 -1
在前面创建子进程的时候就学过了fork函数它能从已经存在进程中创建一个新进程新进程为子进程而原进程为父进程。 当进程调用fork当控制转移到内核中的fork代码后内核做 pid_t fork(void) { 1.分配新的内存块和内核数据结构给子进程2.将父进程部分数据结构内容拷贝至子进程3.添加子进程到系统进程列表当中4.fork返回开始调度器调度 } fork之前父进程独立执行fork之后父子两个执行流分别执行。注意fork之后谁先执行完全由调度器决定。 子进程的特点 1.将父进程的所有数据都 共享或拷贝 到了子进程中。若子进程不对父进程的数据进行修改的话父子进程的数据也是共享的。若子进程对父进程的数据进行修改时会发生写时拷贝将父进程的数据进行拷贝一份到子进程中 写时拷贝 :是一种延时申请技术可以提高整机内存的使用率 2.子进程和父进程的所有代码共享 3.由于 程序计数器 和 CPU中存储上下文数据的寄存器 原因子进程虽然可以共享父进程的所有代码但是在子进程中是从fork()创建子进程之后的代码开始执行的fork()创建子进程之前的代码默认已经执行过不会重复执行所以子进程会执行子进程创建之后的代码。但是由于fork()进行返回值是在子进程创建之后进行返回的所以子进程依然会执行fork()的返回值。 我们之前详细讲过fork函数就不再讨论fork函数了
1.2.创建进程
使用fork函数创建子进程
2.进程退出
2.1. 退出码
通常main函数最后都要有一句return 0这些数字有什么意义吗
int main()
{//...return 0;
}我们可以来看看
#includestdio.h
#includestring.h int AddtoTarget(int from,int end)
{ int sum0; for(int ifrom;iend;i) { sumi; } return sum; } int main()
{ //写代码是为了完成某件事情我们如何得知事情完成的怎么样呢//进程退出码 int numAddtoTarget(1,100);if(num 5050) return 0; else return 1; return 0; } $? 该符号永远记录最近一个进程在命令行中执行完毕时对应的退出码
echo $? //查看进程退出码这里下面的三个0是怎么回事呢
这是因为echo 也是一个子进程因此剩下的三个的是echo ?是一个echo子进程的退出码。 main函数的返回值实际上是 进程的退出码用于表示进程是否是正确返回。 第一种若退出码是0则表示进程正确返回0success。第二种若退出码为非0则表示进程不正确返回并且每个退出码都对应一个报错信息退出码报错信息。意义将返回值返回给上一进程用于监控进程的退出状态。出错时方便定位错误。 有人就说了退出码都是数字我们怎么知道它们分别对应什么错误
还好c语言自带了一个查询退出码的函数——strerror #includestdio.h
#includestring.hint main()
{for(int i0;i200;i){printf(%d: %s\n,i,strerror(i)); } return 0;} strerror记录了对应的退出码的映射信息总共135个这里截取了一小部分。
2.2.进程退出场景 此时代码运行完毕结果正确 这个时候main函数的返回值为0则为正确0success此时代码运行完毕结果不正确这个时候main函数的返回值非0则为不正确返回值报错信息此时代码异常终止这个时候main函数的返回值不具有意义此时应该去看退出信号 2.3.怎么退出进程
2.3.1.main函数return返回其他函数return是调用结束。
return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返 回值当做 exit的参数。
2.3.2.任意地方调用exit。 我们来使用一下
#includestdio.h
#includestring.h
#includeunistd.h
#includestdlib.hint AddtoTarget(int from, int end){int sum 0;for (int i from; i end; i){sum i;}exit(12);// return sum; }int main(){int ret AddtoTarget(1, 100);if (ret 5050)return 0;elsereturn 1;} 2.3.3.任意地方调用_exit了解 我们来使用一下
#includestdio.h
#includestring.h
#includeunistd.h
#includestdlib.hint AddtoTarget(int from, int end){int sum 0;for (int i from; i end; i){sum i;}_exit(12);// return sum; }int main(){int ret AddtoTarget(1, 100);if (ret 5050)return 0;elsereturn 1;}
对比exit和_exit发现都可以使进程再任意地方结束。
2.3.4.exit()和_exit()的区别 我们先来看两段代码 #includestdio.h
#includestring.h
#includeunistd.h
#includestdlib.h
int main()
{printf(hello linux);sleep(2);exit(1);
}#includestdio.h
#includestring.h
#includeunistd.h
#includestdlib.h
int main()
{printf(hello linux);sleep(2);_exit(1);
} 对比发现exit会刷新缓存区而_exit并不会刷新缓存区——说明exit可能会调用_exit。 事实上 exit()和_exit()的底层区别:
_exit()_exit()是系统调用接口的函数。exit()而exit()是把_exit()封装在内并且增加了其他的函数共同组合成exit()——是一个库函数。
exit是库函数_exit是系统调用。库函数在系统调用上面。 如果缓存区在内存exit调用_exit去终止进程exit/_exit都应该会刷新缓冲区。所以缓冲区在用户空间是用户级的缓冲区。 2.3.5.异常退出 ·ctrl c信号终止