Hi,百无聊赖写blog。本文所涉及的所有内容是存在笔者没有发现的错误的,所以请以批判的角度阅读,希望高手留下珍贵的留言,于此感激不尽。
然后,这些是记录笔者个人对有关知识点的认知和理解,希望在recording的同时,能够提高我的英语词汇运用,也能够将自己对C语言的热爱,开源和分享的思想在社区传播。
Alright!Nonsense is over,let's get into the code world!
First: 代码素材
#include
#include
#include
#include
void testFork(); //demo1
void testSleep();//demo2
void testWait(); //demo3
void testExit(); //demo4
int main(){
//testFork();
//testSleep();
//testWait();
//testExit();
return 0;
}
void testFork(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
printf("there is child;\n");
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
}
}
}
void testSleep(){
int i;
if(fork() != 0){
for(i=0;i<3;i++){
printf("there is father;\n");
sleep(1);
}
}
else{
for(i=0;i<3;i++){
sleep(1);
printf("there is child;\n");
}
}
}
void testWait(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
sleep(1);
printf("there is child;\n");
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
wait();
}
}
}
void testExit(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
printf("there is child;\n");
exit(0);
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
}
}
}
首先在本人的认知范围内介绍我们的fork()函数:
有关代码如下:
void testFork(); //demo1
int main(){
testFork();
return 0;
}
void testFork(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
printf("there is child;\n");
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
}
}
}
首先,从函数名fork入手,fork这个单词有分岔的含义。它的作用是当调用到fork函数时,在内存中复制一个当前进程(包括数据)的镜像,然后这个新的镜像进程(即子进程)和旧的进程(即父进程)并发执行。
接下来我们关心的是调用fork函数会返回哪些值
①在父进程中,fork返回新创建子进程的进程ID
②在子进程中,fork返回0
③如果调用中出现错误,那么fork返回复制
好,到这一步我们可以看看代码,if语句中调用了fork函数,与0进行等价逻辑判断,因为从调用fork函数开始,就相当于分岔开始了。此时,在父进程中fork返回值为非0,那么父进程执行else语句,而新创建的子进程执行if中的语句。
执行结果如下:
P-1
这里应该注意到,不管这个if-else语句如何进行逻辑重写,都是先执行子进程的代码,然后再执行父进程的代码
介绍sleep函数:
void testSleep();//demo2
int main(){
testSleep();
return 0;
}
void testSleep(){
int i;
if(fork() != 0){
for(i=0;i<3;i++){
printf("there is father;\n");
sleep(1);
}
}
else{
for(i=0;i<3;i++){
sleep(1);
printf("there is child;\n");
}
}
}
顾名思义,sleep函数就是休眠,睡大觉的意思。那么当代码执行到这个函数时,它就会使这个进程(配合fork函数使用时)暂时休眠,然后执行下一个进程(在这里执行的是父进程)。注意这段代码中笔者刻意将if中的等价逻辑判断改成了不等价逻辑判断。
此时我们关注一下sleep函数的参数
unsigned sleep(unsigned seconds)
这个秒是以毫秒为单位的,并非seconds的秒
那么该程序的执行结果如下:
P-2
笔者认为,两个进程睡了1毫秒后,谁先醒谁就先执行。那么,这个程序结果是不唯一的,笔者认为应该避免这种情况。从执行结果知道,父进程跳出for之后就是子进程执行,全部执行完之后,才结束程序。
下一步就是看一下我们的wait函数:
void testWait(); //demo3
int main(){
testWait();
return 0;
}
void testWait(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
sleep(1);
printf("there is child;\n");
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
wait();
}
}
}
wait函数,可以让我们的进程进入等状态,然后直到有信号来或子进程结束之后,再执行其本身。
wait()函数的定义为:
pid_t wait(int *status)
执行结果如下:
P-3
在这里就是父进程进入等状态然后让子进程执行完了之后再轮到父进程执行。
好,最后一个就是exit函数
void testExit(); //demo4
int main(){
testExit();
return 0;
}
void testExit(){
int i;
if(fork() == 0){
for(i=0;i<3;i++){
printf("there is child;\n");
exit(0);
}
}
else{
for(i=0;i<3;i++){
printf("there is father;\n");
}
}
}
exit就是退出,结束的意思啦,那么我们先看该函数的定义
void exit(int status)
笔者认为,当你传入参数0时,表示让该进程正常退出,当你传入非0参数时,表示异常退出
执行结果如下:
P-4
如上结果可知,子进程被结束掉了,那么就只剩父进程了输出最后结束
好,那么笔者想分享一些技巧,当你面对着一个陌生的函数时,首先是了解它的参数,函数名,返回值,然后让你深入了解它最好的方法就是用黑盒测试的思想方法,从编写一个简单的测试程序开始,不断的深入,不断挖掘其中的各种变化。
记住,只有充满好奇心,你才能获得真正的知识!
Remember that only being full of curiosity, you will hold the precious knowledge!
Sincerely, it's the best honor for me if you got some ideas from this blog!
See you!