更多点子:linux—目录索引(知识小渠道)
两次fork 可以让两个进程同时运行,一次fork 只能一个运行一个阻塞
在子进程里再调一个进程,然后让儿子死亡,孙子成孤儿,之后父亲和孙子一起并发运行
#include<stdio.h>
#include<std;lib.h>
#include<string.h>
#include<sys/wait.h>
int main(void)
{
pid_t pid = fork();
if(pid==0)//子进程
{
if(fork()>0)//子进程本身,说明孙子创建失败了
exit(0);
for(;;)
{
printf("孙子\n");
sleep(1);
}
else
{
wait(NULL);
for(;;)
{
printf("老子\n");
sleep(1);
}
}
}
}
编写xshell
WIFEXITED(status) // 如果正常退出,返回真
WEXITSTATUS(status) //如果正常退出,返回退出码
WIFSIGNALED(status) // 如果被信号打断,返回真
WTERMSIG(status) // 如果被信号打断,得到信号值
pid_t waited(pid_t pid,int *status,int options); //0 WNOHANG
pid > 0 等待进程ID等于pid的子进程死亡
pid = 0 调用者进程所在进程组的任何一个子进程死亡
pid = -1 等待任何一个子进程死亡
pid < -1 |pid|进程组的任何一个子进程死亡
exec 替换进程空间,但这不是一个函数,是一批函数,下面的enecvp只是其中的一个
进程空间替换(磁盘到虚拟):
本来进程有虚拟的空间,现在到磁盘上到一段空间,来放进程的数据
PDB不替换
int execvp(const char *file,char *const argv[]) //用file(可执行程序名)替换这个进程,占用它的空间
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<ctype.h>
void do_enecvp(int argc,char* argv[])
{
pid_t pid=fork();
if(pid==0)//子进程
{
execvp(argv[0],argv);//替换子进程,执行它
perror("execvp");//如果命令不存在,会出错
exit(0);//能执行到这,就说明已经出错了,退出吧
}
wait(NULL);//父进程等待子进程死亡,子进程是这的envp
}
void do_parse(char *buf)
{
char *argv[8]={};
int argc=0;
int i;
int status=0;
for(i=0;buf[i]!=0;i++)//重置buf内各个的状态
{
if(status==0&&!isspace(buf[i]))//非空白符
{
argv[argc++]=buf+i;
status=1;
}
else if(isspace(buf[i]))//空白符
{
status=0;
buf[i]=0;//拿这把字串隔开
}
}
argv[argc]=NULL;
do_execvp(argc,argv);//让父进程等待,子进程运行,所以把它给传过去
}
int main(void)
{
char bur[1024]={};
while(1)
{
printf("my shell> ");
memset(buf,0x00,sizeof(buf));
while(scanf("%[~\n]%*c",buf)==0)//不接收\n,然后读取\n丢弃,如果一上来就是\n,那后面的就不读了,就会导致换行一直在输入缓存,就一直在循环
{
//==0说明scanf没有成功,成功的话返回2
printf("my shell> ");
while(getchar()!="\n");//走到这说明scanf没有成功,所以要把这一行给清空
}
if(strncmp(buf,"exit",4)==0)//如果输入的是exit就结束掉当前进程
exit(0);
do_parse(buf);
}
}
如果有什么不对的地方,可以评论告诉我,望指导!