马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
🌟 各位看官好,我是maomi_9526!
🌍 种一棵树最好是十年前,其次是现在!
🚀 本日来学习C语言的干系知识。
👍 如果以为这篇文章有资助,欢迎您一键三连,分享给更多人哦
目次
1. 历程创建
1.1fork函数
编辑
1.2写时拷贝(Copy-on-write)
1.3 假造地点存储
2. 历程停止
2.1历程退出环境
2.2退出方式
2.3退出码
2.4exit函数VS_exit函数
2.4.1exit函数
2.4.2_exit函数
2.4.3eixt VS_exit
3. 历程等候
3.1历程等候的须要性
3.2wait等候
3.3获取子历程status
3.3.1退出码
3.3.2停止信号
3.3.3 WIFEXITED
3.3.4WEXITSTATUS
3.4非壅闭查询(wnohang)和壅闭查询(0)
4.总结
1. 历程创建
1.1fork函数
fork() 是 Linux 中非常紧张的函数,用来从父历程创建一个子历程。父历程返回子历程的PID,子历程返回0。通过 fork() 创建的父子历程可以独立执行各自的代码。
头文件:#include<unistd.h>
返回值:乐成父历程返回孩子pid,子历程返回0。失败返回-1。
函数:pid_t frok(void);
- #include<stdio.h>
- #include<unistd.h>
- int main()
- {
- printf("Befor pid is %d\n",getpid());
- pid_t id=fork();
- if(id==-1)
- {
- perror("fork()");
- exit(1);
- }
- printf("After:pid is %d,return id is %d \n",getpid(),id);
- }
复制代码 结果:
1.2写时拷贝(Copy-on-write)
fork() 使父子历程共享相同的内存内容,直到其中一个历程对内存举行修改,这时才会举行拷贝,制止不须要的资源浪费。
- #include<stdio.h>
- #include<unistd.h>
- #include<sys/types.h>
- #include<stdlib.h>
- int main()
- {
- int a=0;
- printf("Befor pid is %d\n",getpid());
- pid_t id=fork();
- if(id==-1)
- {
- perror("fork()");
- exit(1);
- }
- printf("After:pid is %d,return id is %d \n",getpid(),id);
- }
复制代码 此时三个地点:a取地点一样
1.3 假造地点存储
实行在子历程中修改a的地点后,查看a的地点。
- #include<stdio.h>
- #include<unistd.h>
- #include<sys/types.h>
- #include<stdlib.h>
- int main()
- {
- int a=0;
- printf("Befor pid is %d,path is %p\n",getpid(),&a);
- pid_t id=fork();
- if(id==-1)
- {
- perror("fork()");
- exit(1);
- }
- if(id==0)
- {
- a=15;
- printf("After:pid is %d,return id is %d ,path is %p,a is %d\n",getpid(),id,&a,a);
- }
- else
- printf("After:pid is %d,return id is %d ,path is %p,a is %d\n",getpid(),id,&a,a);
- }
复制代码
三个地点仍旧相同?这是为什么呢?
两个假造地点相同的原因在于它们位于差别的假造页面上,但在各自的假造页面内,偏移量相同。因此,只管它们属于差别的假造内存块,最终的假造地点值却相同。
2. 历程停止
2.1历程退出环境
- 代码运行完毕,结果正常
- 代码运行完毕,结果不正常
- 历程非常停止
2.2退出方式
如果体系正常停止可以通过$?来查看历程退出码
2.3退出码
每个历程都有一个退出码,0 体现正常退出,非 0 体现堕落。
2.4exit函数VS_exit函数
2.4.1exit函数
#include <unistd.h>
#include<stdlib.h>
void exit(int status);
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- int main()
- {
- printf("exit");
- exit(1);
- }
复制代码
2.4.2_exit函数
#include <unistd.h>
#include<stdlib.h>
void _exit(int status);
- #include<stdio.h>
- #include<unistd.h>
- int main()
- {
- printf("_exit");
- _exit(1);
- }
复制代码 2.4.3eixt VS_exit
3. 历程等候
3.1历程等候的须要性
- 之前讲过,子历程退出,父历程如果不管不顾,就大概造成‘僵尸历程’的题目,进而造成内存
- 走漏。
- 别的,历程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,由于谁也没有办法杀死一个已经死去的历程。
- 最后,父历程派给子历程的任务完成的怎样,我们须要知道。如,子历程运行完成,结果对还是不对,大概是否正常退出。
- 父历程通过历程等候的方式,接纳子历程资源,获取子历程退出信息
3.2wait等候
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
返回值:
乐成返回被等候历程pid,失败返回-1。
参数:
输出型参数,获取子历程退出状态,不关心则可以设置成为NULL
pid_t waitpid(pid_t pid, int *status, int options);
返回值:
当正常返回的时间waitpid返回网络到的子历程的历程ID;
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子历程可网络,则返回0;
如果调用中堕落,则返回-1,这时errno会被设置成相应的值以指示错误所在;
参数:
pid:
Pid=-1,等候任一个子历程。与wait等效。
Pid>0.等候其历程ID与pid相称的子历程。
status:
输出型参数
WIFEXITED(status): 若为正常停止子历程返回的状态,则为真。(查看历程是否是正常退出)
WEXITSTATUS(status): 若WIFEXITED非零,提取子历程退出码。(查看历程的退出码)
options:默认为0,体现壅闭等候
WNOHANG: 若pid指定的子历程没有竣事,则waitpid()函数返回0,不予以等
待。若正常竣事,则返回该子历程的ID。
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
3.3获取子历程status
- #include<stdio.h>
- #include<sys/types.h>
- #include<sys/wait.h>
- #include<unistd.h>
- #include<stdlib.h>
- int main()
- {
- int id=0;
- int cur=5;
- id=fork();
- if(id==-1)
- {
- perror("fork");
- }
- if(id==0)
- {
- while(cur--)
- {
- printf("My pid is %d,My ppid is %d\n",getpid(),getppid());
- }
- sleep(1);
- exit(1);
- }
- int status=0;
- int idd=waitpid(id,&status,0);
- printf("idd is %d,status is %d\n",idd,status);
- }
复制代码
3.3.1退出码
为什么退出码是256而不是1?
- printf("idd is %d,status is %d\n",idd,(status>>8));
复制代码
3.3.2停止信号
3.3.3 WIFEXITED
是一个宏值,与&0x7F取得的结果相仿
步伐正常运举动:真
步伐非常退出为:假
3.3.4WEXITSTATUS
是一个宏值,与(>>8)&&0xFF取得的结果雷同
3.4非壅闭等候(wnohang)和壅闭等候(0)
- #include<stdio.h>
- #include<sys/types.h>
- #include<sys/wait.h>
- #include<unistd.h>
- #include<stdlib.h>
- int main()
- {
- int id=fork();
- if(id==-1)
- {
- perror("fork error");
- }
- if(id==0)
- {
- int cur=5;
- while(cur--)
- {
- printf("My pid is %d,my ppid is %d\n",getpid(),getppid());
- }
- exit(1);
- }
- //父进程
- int status=0;
- int idd=waitpid(id,&status,0);//阻塞等待
- //int idd=waitpid(id,&status,WNOHANG);//非阻塞等待
- if(idd>0)
- {
- printf("退出码:%d",WEXITSTATUS(status));
- }
- }
复制代码 4.总结
1.Linux下的错误码及形貌
|