当前位置:首页>Linux>Linux进程控制

Linux进程控制

  • 2026-07-02 16:33:52
Linux进程控制

1进程创建

初始fork函数

认识fork函数

分配新的内存块和内核数据结构给子进程 

将父进程部分数据结构内容拷贝至子进程 

添加子进程到系统进程列表当中 

fork返回,开始调度器调度

fork返回值

fork的返回值  已经进行了写时拷贝了,这也是用来分流的关键用法。

fork之后代码共享,两个执行流。

1一个函数两个返回值 

return之前 已经有两个执行流了

2如何理解fork返回之后, 给父进程返回子进程的pid,给子进程返回 0?  父亲 : 孩子 == 1 : n。 唯一性

fork返回的时候已经开始分流的。返回的时候,写时拷贝的。

3 同一个id两个值,if eles同时执行的 

复习

系统级别的环境变量,适用不同的场景 。 全局环境变量具有全局属性的。 子进程可以继承下去的。

echo  内置指令

命令行参数, 根据不同的选项执行不同的功能。 命令行参数 

环境变量表  getenv  main函数  extern char* environ

进程地址空间 : 先见见现象, 地址一样,值不一样。这里是虚拟地址。进程地址空间。

OS让进程感觉自己独享空间,设计理念。 进程并不知道进程的关系,进程的独立性。

进程地址空间的管理:本质就是一堆的刻度管理(刻度在PCB里面的)。mm_struct管理起来的。_start  _end管理

虚拟地址空间也是需要管理起来的。mm_struct进行管理的。

页表映射数据

写实拷贝

进程地址空间的意义

mm_struct 的初始化 就是你编译好的代码的地址,已经可以初始化的数据 可以有地址的数据。栈区等加载到内存在进行初始化的

两套地址 

进程创建

写时拷贝

创建子进程:继承父业,实现新的梦想。

2进程终止

return, exit, _exit

0表示成功,!0表示失败。不同的零,需要标识不同的错误信息,不同的错误描述码。

return 0

#include <stdio.h>
#include <string.h>
intmain()
{
for(inti=0i<200++i)
    {
printf("%d : %s \n"istrerror(i));
    }

// 进程的退出码,用于标定进程是否正确退出成功。
return0
}

?是shell的一个变量,永远记录最近一个进程的退出码,main--->return

echo $?

一般而言退出码,都需要对应的描述信息。

进程退出一般三种情况

进程如何退出的问题

mian函数 return 

任意地方的exit函数退出 

_exit函数,操作系统的内核函数,不会管用户空间内存的数据的。

功能returnexit()
结束的是当前函数整个进程
是否执行 atexit 回调✔ 是✔ 是
是否刷新 stdout 缓冲区✔ 是✔ 是
能否在普通函数中结束程序❌ 不行✔ 可以
能否跳出多层函数❌ 不行✔ 可以
用于致命错误退出不常用✔ 常用
用于正常结束程序✔ 推荐不常用(除非必要)
#include<stdio.h>      
#include<unistd.h>      
#include<string.h>      
#include<stdlib.h>      


intaddto(intfromintto)      
{      
intsum=0;      
for(inti=fromi<=toi++)      
  {      
sum+=i;      
  }                                                                                                                                                                                                  
exit(21);
/*                                                                           
*_exit(21)                                                                    
*/


intmain()
{
printf("hello lichermionex ");         
add(1100);

return0;
}

_exit函数终止不会主动刷新缓冲区,exit函数会刷新缓冲区的。

底层exit    调用  _exit函数的。

exit函数是用户层函数

缓冲区在哪里呢: 用户层的 不会在OS里面的。

缓冲区用户层的一块内存里面。

3进程等待

z状态,僵尸状态。

进程等待,解决僵尸进程的问题。

wait函数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

intmain()
{
pid_tid=fork(); 
if(id==0)
  {
intcnt=10;
while(cnt)
    {
printf("子进程ppid:%d,pid:%d, cnt=%d\n"getppid(), getpid(), cnt--);
sleep(1);
    }

exit(0);
  }

sleep(15);
pid_tret=wait(NULL);
if(ret>0)
  {
printf("wait success child id : %d\n"ret);
  }
return0;
}
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

intmain()
{

pid_tid=fork();
assert(id>=0);

if(id==0)
  {
printf("I AM CHILD, I am running  pid : %d\n"getpid());
sleep(3);
exit(13);
printf("I AM CHILD, I am ending  \n");
  }
else
  {

// 退出的信号    
// exit退出
// termial退出    
//    
printf("I am waiting child ,,,,\n");                                                                                                                                                                            
intstatus=0;    
pid_tchild_pid=wait(&status);    

// printf("%d \n", (status >> 8) & 0XFF );    

// wait if exited    
if(WIFEXITED(status)) // wait if exited退出    
    {    
printf("eixt code : %d \n",WEXITSTATUS(status)); // wait exit status    
    }    

// wait if signaled    
if(WIFSIGNALED(status)) // wait if signaled 退出    
    {    
printf("signal code : %d \n"WTERMSIG(status)); // wait terminal signal    
    }    

printf("status : %d \n"status);    
printf("child_pid : %d \n"child_pid);    
printf("I am waiting child success \n");    
  }    

// wait是阻塞式等待,直到子进程退出    
// 成果了返回子进程的PID, 失败返回-1    
// 输出的信息在,输出型参数里面    

// WIFEXITED(status) 
// WEXITSTATUS(status) 

// WIFSIGNALED(status)
// WTERMSIG(status)

// 正常退出的时候退出码就是零
// 不正常退出的时候,退出码在8-15

return0;
}

用途
WIFEXITED(status)子进程是否正常退出
WEXITSTATUS(status)子进程的 return/exit 退出码
WIFSIGNALED(status)子进程是否被信号杀死
WTERMSIG(status)导致退出的信号号

四个宏

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

intmain()
{
pid_tid=fork();
if(id==-1)
  {
perror("fork");
return1;
  }

if(id==0)
  {
intcnt=10;
while(cnt)
    {
printf("子进程,ppid:%d, pid:%d, cnt:%d\n"getppid(), getpid(), cnt);
--cnt;
sleep(1);
    }

return12;
  }

intstatus=0;
intret=waitpid(id&status0);
if(ret<0)
  {
perror("waitpid");
return1;
  }

if(WIFEXITED(status))
  {
printf("%d正常退出,退出码:%d\n"retWEXITSTATUS(status));
  }
elseif (WIFSIGNALED(status))
  {
printf("%d信号退出,退出信号:%d\n"ret,WTERMSIG(status));
  }
elseif (WIFSTOPPED(status))
  {
printf("%d暂停,暂停信号:%d\n"ret,WSTOPSIG(status));
  }

return0;
}

wait的返回值信息

#include <unistd.h>    
#include <sys/wait.h>    
#include <sys/types.h>    
#include <stdio.h>    
#include <string.h>    
#include <assert.h>    


intmain()    
{    
pid_tid=fork();                                                                                                                                                                                                
if(id==0)       
  {          
intcnt=10;
while(cnt)   
    {         
printf("我是子进程:%d, 父进程的:%d , %d \n"getpid(), getppid(), cnt--);
sleep(1);                                                                 
    }          
  }  
sleep(15);
pid_tret=wait(NULL);  // 返回值就是等待子进程的pid
if(id>0)             
  {                      
printf("wait success :%d \n"ret);
  }                                    
return0;                            
}  

waitpid的输出型参数

#include <unistd.h>    
#include <stdlib.h>    
#include <sys/wait.h>    
#include <sys/types.h>    
#include <stdio.h>    
#include <string.h>    
#include <assert.h>    


intmain()    
{    
pid_tid=fork();    
if(id==0)    
  {    
intcnt=5;    
while(cnt)    
    {    
printf("我是子进程:%d, 父进程的:%d , %d \n"getpid(), getppid(), cnt--);    
sleep(1);    
    }    
exit(10);                                                                                                                                                                                                       
  }    
sleep(10);    
intstatus=0;    
// 15-8退出状态    
// 7core dump    
// 6-0终止信号    
pid_tret=waitpid(id&status0);    
if(id>0)    
  {  
// 111 1111
printf("wait success : ret : %d,  sig number : %d, child exit code : %d  \n"ret, (status&0x7F), (status>>8)&0xFF);

  }    
return0;    
}   

僵尸进程的信息放在那里呢?

检查子进程的退出信息, 

复习

进程创建

创建PCB,地址空间,页表,映射,进程代码和数据load到内存里面

进程退出

释放资源,变成僵尸,父进程读取

退出exit和_exit用户级别的缓冲区

从退出进程的tast_struct中获取。1.进程退出会变成僵尸,会把自己的退出结果写入到自己的task_struct2.wait和waitpid是一个系统调用,os os有资格也有能力去读取子进程的task_struct

等待wait waitpid

等等主要是两件事情

1.让OS释放子进程的僵尸状态

2.获取子进程的退出状态信息。

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/wait.h>    
#include <sys/types.h>    
#include <assert.h>    

intmain()    
{    

pid_tid=fork();    
assert(id!=-1);    

if(id==0)    
  {    
intcnt=10;    
while(cnt)    
    {    
printf("child runing, pid : %d, ppid : %d, cnt : %d \n"getpid(), getppid(), cnt--);    
sleep(1);    
    }    
exit(10);                                                                                            
  }    

intstatus=0;    
intret=waitpid(id&status0);    
if(ret>0)    
  {    
printf("wait success, exit code : %d , sig number : %d \n", (status>>8)&0xFFstatus&0x7f);    
  }    

return0;    
}  
 30     // 是否正常退出
 31     if(WIFEXITED(status))
 32     {
 33       printf("exit code : %d \n", WEXITSTATUS(status)); // 运行结果的
 34     }    

wait, waitpid是一个系统调用函数

阻塞和非阻塞

阻塞和非阻塞等待的状态

阻塞等待

多次非阻塞等待---就是轮询

轮询等 WNOHONG

waitpid: 返回值==零,子进程的状态没有发生任何变化。指定宏WNOHONG.

waitpid:返回值== -1,发生错误了的。

waitpid:返回值 > 0, 子进程的pid。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <assert.h>

int main()
{

  pid_t id = fork();    
  assert(id != -1);    

  // 子进程
  if(id == 0)    
  {    
    int cnt = 10;    
    while(cnt)    
    {    
      printf("child runing, pid : %d, ppid : %d, cnt : %d \n", getpid(), getppid(), cnt--);    
      sleep(1);    
    }    
    exit(10);    
  }    

  // 父进程
  int status = 0;    
  while(1)    
  {    
  int ret = waitpid(id, &status, WNOHANG); // 非阻塞等待,只会检查一次的哦。                                                                                                                                                          
      if(ret == 0)    
      {    
        // waitpid调用成功,子进程没有退出    
        // 子进程没有退出,我的waitpid没有等待失败,仅仅是是检测到了子进程没有退出,    
        printf("真正等待中、\n");    
        sleep(1);    
      }    
      else if(ret > 0)    
      {    
        // waitpid调用成功,子进程退出了    
        printf("wait sucess \n");    
        break;    
      }    
      else  // waitpid调用失败了的。
      {    
        printf("等待失败了、\n");    
        break;    
      }    
  }  

   return 0;
}

非阻塞等待好处?不会占用父进程的所有精力,可以轮询期间干干别的!

#include <stdio.h>    
#include <string.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/wait.h>    
#include <sys/types.h>    
#include <assert.h>    

#define NUM 10    
typedef void (*func_t)();     

void task1()    
{    
  printf("task1 \n");    
}    

void task2()    
{    
  printf("task2 \n");    
}    

void task3()    
{    
  printf("task3 \n");    
}    

func_t handerTask[NUM];    

void loadTask()    
{    
  memset(handerTask, 0, sizeof(handerTask));    
  handerTask[0] = task1;    
  handerTask[1] = task2;    
  handerTask[2] = task3;    
}    


int main()    
{    
  pid_t id = fork();    
  assert(id != -1);    
  if(id == 0)    
  {    
    int cnt = 10;    
    while(cnt)                                                                                                                                                                                      
    {    
      printf("child runing, pid : %d, ppid : %d, cnt : %d \n", getpid(), getppid(), cnt--);    
      sleep(1);    
    }  
      exit(10);    
  }

  loadTask();
  int status = 0;
  while(1)
  {
      int ret = waitpid(id, &status, WNOHANG); // 非阻塞等待,
      if(ret == 0)
      {
        // waitpid调用成功,子进程没有退出
        // 子进程没有退出,我的waitpid没有等待失败,仅仅是是检测到了子进程没有退出,
        printf("正在等待中、\n");  
        for(int i = 0; handerTask[i] != NULL; i++)
        {
          handerTask[i]();
        }
        sleep(1);
      }
      else if(ret > 0)
      {
        // waitpid调用成功,子进程退出了
        printf("wait sucess \n");
        break;
      }
      else 
      {
        printf("等待失败了、\n");
        break;
      }
  }
  return 0;
}

4进程程序替换

原理

进程替换1.创建子进程的目的让子进程执行父进程的一部分。执行父进程对应磁盘代码中的一部分。让子进程执行一个全新的程序,让我们的子进程想办法,加载磁盘上指定的程序,执行新程序的代码和数据。

程序替换的本质,就是将指定的程序和代码+数据 加载到指定的位置, 覆盖自己的代码和数据。

#include <stdio.h>    
#include <string.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/wait.h>    
#include <sys/types.h>    
#include <assert.h>      

int main()    
{    

  printf("process is runing ...\n");    

  execl("/usr/bin/ls", "ls", "-a", "-l" ,NULL); // exec系列 必须是NULL结尾。  
  // execl("/usr/bin/lssdgdfg", "ls", "-a", "-l" ,NULL); // 函数失败,不会替换
  // 只需要错误的返回值

  printf("process is runing ...\n");    // 不执行这条语句
  // printf也是代码,是在execl之后,是在execl执行完毕,代码已经完全覆盖了,开始执行新的代码了,无法执行printf了。


  return 0;    

exec*为什么没成功返回呢? 因为成功了,和接下来的代码无关了,判断毫无意义了。

exec*只有返回 就是一定的错误的。 错误返回-1的。

exec*  将程序加载到内存里面。

exec* 加载器

execve 就这一个函数

execve是系统调用, 其它的都是封装起来的。

这些函数调用 不要省略。

程序替换系列

execl

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  printf("process is running ...\n");
  /*
   *execl("/usr/bin/ls","ls", "-a", "-l","-h", "/usr/bin/", NULL);
   */
  execl("/usr/bin/top","top", NULL);
  // 第一个参数,可执行文件的位置
  // 第二个参数,终端是如何执行的
  // 第三个参数,NULL结尾

 printf("process is ending ...\n");
  return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    execl("/usr/bin/lsaaa", "ls", "-a", "-l", "-h", NULL);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

一般的写法

子进程替换原理

execl

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    execl("/usr/bin/lsaaa", "ls", "-a", "-l", "-h", NULL);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execlp

l:list列出如何执行的,

p:path 如何找到程序,带 p会从环境变量查找的。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    // 1.一个参数告诉系统我要执行谁
    // 2.一个参数告诉系统我要如何执行的。
    // execlp("ls", "ls", "-a", "-l", "-h", NULL);
    // execlp("pwd","pwd", NULL);
     execlp("top","top", NULL);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execv

v:vector。所有的执行参数放到vector里面,不使用可变参数的。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const argv_[] = {"ls" , "-a", "-l", "-h", NULL};
    execv("/usr/bin/ls", argv_);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execvp

v:数组里面如何执行,p:环境变量里面找

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const argv_[] = {"ls", "-a", "-l", "-h", NULL};
    execvp("ls", argv_);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execle

code1

用自己的环境变量

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const envp[] = {"NAME=lic", "AGE=20", NULL};
    execle("/usr/bin/env", "env", NULL, envp);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

code2

添加到系统的环境变量中去的

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

extern char** environ;

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* info = "NAME=lic";
    putenv(info);
    execle("/usr/bin/env", "env", NULL, environ);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

exec*加载器

进程地址空间拿到环境变量的信息,子进程的。这就是为什么子进程可以 继承环境变量的。

execve只有一个的。其它都是c语言的封装信息的。

execl   // 参数列表
execv   // 参数数组
execle  // 参数列表 + 环境变量
execve  // 参数数组 + 环境变量
execlp  // 参数列表 + 自动搜索PATH
execvp  // 参数数组 + 自动搜索PATH
execve  系统调用的

5自定义shell

 #include <stdio.h>    
  #include <string.h>    
  #include <string.h>    
  #include <unistd.h>    
  #include <stdlib.h>    
  #include <sys/wait.h>    
  #include <sys/types.h>    
  #include <assert.h>    

  #define NUM 1024    
  #define OPT_NUM 64    
  char lineCommand[NUM];    
  char* myargv[OPT_NUM];    


int main(int argc, char* agrv[])    
  {    
    while(1)    
    {    

    // 获取用户输入    
    printf("用户名@主机名:当前路径# ");    
    fflush(stdout);    

    // 获取用户输入信息    
    char* s = fgets(lineCommand, sizeof(lineCommand) - 1, stdin);    
    assert(s != NULL);    
    (void)s;    

    // 清除最后一个\n    
    lineCommand[strlen(lineCommand) - 1] = 0;    
    /*printf("test : %s \n", lineCommand);*/    


    // 循环切割    

    myargv[0] = strtok(lineCommand, " ");    
    int i = 1;    

  while(myargv[i++] = strtok(NULL, " "));    

    /*    
     *for(int i = 0; myargv[i]; i++)    
     *{    
     *  printf("%d : %s \n", i, myargv[i]);     
     *}    
     */                                                                                                                                                                                                             

    // 执行指令了      

    pid_t id = fork();    
    assert(id != -1);    
            if(id == 0)
    {
      execvp(myargv[0], myargv);
      exit(1);
    }

    int status = 0;
    waitpid(id, &status, 0);

    }

复习

子进程的退出码和退休信号

程序替换的七个函数,本质上都是一个系统函数, 6个封装函数。

子进程执行一个全新的 程序。

如何找到,怎么执行

程序替换是系统级别的替换。

环境变量 可以被子进程进程。

execve系统函数,其它封装满足不同的场景。

复习

shell

当前路径

进程当前在那个工作目录下面的

chdir

#include <stdio.h>    
#include <unistd.h>    
#include <sys/wait.h>    
#include <sys/types.h>    

int main()    
{    

  chdir("/root/linuxx");                                                                                 
  pid_t id = fork();    

  if(id == 0)    
  {    
    while(1)    
    {    
      printf("running.... id : %d, pid : %d\n", getpid(), getppid());    
      sleep(2);    
    }    
  }    

  wait(NULL);    
  return 0;    
}    

自定义shell和内建指令

#include <stdio.h>    
  #include <string.h>    
  #include <string.h>    
  #include <unistd.h>    
  #include <stdlib.h>    
  #include <sys/wait.h>    
  #include <sys/types.h>    
  #include <assert.h>    

  #define NUM 1024    
  #define OPT_NUM 64    
  char lineCommand[NUM];    
  char* myargv[OPT_NUM];    
  int lastCode = 0;    
  int lastSig = 0;    

  int main()    
  {    
    while(1)    
    {    

    // 获取用户输入    
    printf("用户名@主机名:当前路径# ");    
    fflush(stdout);    

    // 获取用户输入信息    
    char* s = fgets(lineCommand, sizeof(lineCommand) - 1, stdin);    
    assert(s != NULL);    
    (void)s;    

    // 清除最后一个\n    
    lineCommand[strlen(lineCommand) - 1] = 0;    
    /*printf("test : %s \n", lineCommand);*/    


    // 循环切割    

    myargv[0] = strtok(lineCommand, " ");                                                                                                                                    
    int i = 1;    
    if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)    
    {    
      myargv[i++] =(char*) "--color=auto";    
    }    

      while(myargv[i++] = strtok(NULL, " "));

  // cd命令,不需要创建子进程让shell自己执行对应的cd指令                                                                                                                     
  // 像这种不需要让我们子进程来执行,而是让shell自己执行的命令,内建内置命令
  // echo 
    if(myargv[0] != NULL && strcmp(myargv[0], "cd") == 0)
    {
      if(myargv[1] != NULL) chdir(myargv[1]);
      continue;
    }

    if(myargv[0] != NULL && myargv[1] != NULL && strcmp(myargv[0], "echo") == 0)
    {
      if(strcmp(myargv[1], "$?") == 0)
      {
        printf("%d, %d\n", lastCode, lastSig);
      }
      else 
      {
        printf("%s\n", myargv[1]);
      }

      continue;
    }

    /*
     *for(int i = 0; myargv[i]; i++)
     *{
     *  printf("%d : %s \n", i, myargv[i]); 
     *}
     */

    // 执行指令了  

    pid_t id = fork();
    assert(id != -1);

          if(id == 0)
    {
      execvp(myargv[0], myargv);
      exit(1);
    }

        int status = 0;
        pid_t ret = waitpid(id, &status, 0);
        assert(ret > 0);
        (void)ret;
        lastCode =  WIFSIGNALED(status);
        lastSig =  WTERMSIG(status);
    }

code

见见猪跑

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    int cnt = 5;
    while(cnt)
    {
      printf("子进程,ppid:%d, pid:%d, cnt:%d\n", getppid(), getpid(), cnt--);
      sleep(1);
    }

    exit(0);
  }

  sleep(7);
  int status = 0;
  pid_t ret = wait(&status);
  printf("wait success, pid : %d\n", ret);
  return 0;
}

进程退出码和退出信号的

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    int cnt = 20;
    while(cnt)
    {
      printf("子进程,ppid:%d, pid:%d, cnt:%d\n", getppid(), getpid(), cnt--);
      sleep(1);

      /*
       *int* p = NULL;
       **p = 100;
       */
    }

    //exit(12);
    return 13;
  }

  sleep(7);
  int status = 0;
  pid_t ret = wait(&status);
  printf("wait success, pid : %d, exit_code:%d sig_number %d\n", ret,(status>>8)&0xFF, (status&0X7F));
  return 0;
}

execl

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    // execl:list,需要list可以执行程序的位置,可以执行程序终端的list
    //execl("/usr/bin/ls", "ls", "-a", "-l", "-h", NULL); // execl:l就是list,就和你终端是如何list一样的执行方法。注意需要NULL结尾的。
    //execl("/usr/bin/pwd", "pwd", NULL); // execl:l就是list,就和你终端是如何list一样的执行方法。注意需要NULL结尾的。
    //execl("/usr/bin/touch", "touch", "list.txt", NULL); // execl:l就是list,就和你终端是如何list一样的执行方法。注意需要NULL结尾的。
    execl("/usr/bin/top", "top", NULL); // execl:l就是list,就和你终端是如何list一样的执行方法。注意需要NULL结尾的。
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execlp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    // execlp: 存在list,执行的程序,需要在终端如何list.p path:环境变量里面去找额
    execlp("touch", "touch", "lic.txt", NULL);
    execlp("pwd", "pwd", NULL);
    execlp("ls", "ls", "-a", "-l", "-h", NULL);
    execlp("top","top", NULL);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execle

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

extern char** environ;

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
#if 0
    char* info = "NAME=lic";
// 添加新的环境变量的
    putenv(info);
    execle("/usr/bin/env", "env", NULL, environ);
#else 
    char* const envp_[] = {"NAME=lic","AGE=20","LOVE=lic", NULL};
    execle("/usr/bin/env", "env", NULL, envp_);
#endif
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execv

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const argv1_[] = {"ls" , "-a", "-l", "-h", NULL};
    char* const argv2_[] = {"top", NULL};
    char* const argv3_[] = {"pwd", NULL};
    char* const argv4_[] = {"env", NULL};
    execv("/usr/bin/env", argv4_);
    execv("/usr/bin/pwd", argv3_);
    execv("/usr/bin/top", argv2_);
    execv("/usr/bin/ls", argv1_);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execvp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const argv1_[] = {"ls", "-a", "-l", "-h", NULL};
    char* const argv2_[] = {"pwd", NULL};
    char* const argv3_[] = {"top", NULL};
    execvp("top", argv3_);
    execvp("pwd", argv2_);
    execvp("ls", argv1_);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

execve

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

extern char** environ;

int main()
{
  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    char* const argv_[] = {"env", NULL};
    char* info = "NAME=lic------------------------------------";
    putenv(info);
    execve("/usr/bin/env", argv_, environ);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret == -1)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("wait success exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("wait success sig_num:%d\n", WTERMSIG(status));
  }
  return 0;
}

自定义shell

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>

#define LINE_SIZE 1024
#define ARGVS 64

int main()
{
while(1)
{
  printf("[root@lic exec]#:::");
  fflush(stdout);
  char line[LINE_SIZE];
  char* s = fgets(line, sizeof(line) - 1, stdin);
  assert(s != NULL);
  (void)s;

  /*
   *printf("line:%s\n", line);
   */
  line[strlen(line)-1] = 0; 

  char* arg[ARGVS] = {NULL};
  arg[0] = strtok(line, " ");

  int i = 1;
  while( arg[i++] = strtok(NULL, " "))
  {
    ;
  }

#if 0
  for(int i = 0; arg[i]; ++i)
  {
    printf("%d:%s\n", i, arg[i]);
  }
#endif

  if(strcmp(arg[0], "cd") == 0)
  {
    if(arg[1])
    {
      chdir(arg[1]);
    }
    continue;
  }

  if(strcmp(arg[0], "echo") == 0)
  {
    printf("%s\n", arg[1]);
    continue;
  }

  pid_t id = fork();
  if(id == -1)
  {
    perror("fork");
    return 1;
  }

  if(id == 0)
  {
    execvp(arg[0], arg);
    exit(1);
  }

  int status = 0;
  int ret = waitpid(id, &status, 0);
  if(ret < 0)
  {
    perror("waitpid");
    return 1;
  }

  if(WIFEXITED(status))
  {
    printf("exit_code:%d\n", WEXITSTATUS(status));
  }
  else if (WIFSIGNALED(status))
  {
    printf("sig_num:%d\n", WTERMSIG(status));
  }

  }
  return 0;
}

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-02 23:30:21 HTTP/2.0 GET : https://f.mffb.com.cn/a/495880.html
  2. 运行时间 : 0.739129s [ 吞吐率:1.35req/s ] 内存消耗:4,745.30kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=935bc2e8eb5bb0fef40648729073a7cd
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000511s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000647s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.004581s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.004321s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000665s ]
  6. SELECT * FROM `set` [ RunTime:0.012395s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000852s ]
  8. SELECT * FROM `article` WHERE `id` = 495880 LIMIT 1 [ RunTime:0.104431s ]
  9. UPDATE `article` SET `lasttime` = 1783006221 WHERE `id` = 495880 [ RunTime:0.012929s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.011221s ]
  11. SELECT * FROM `article` WHERE `id` < 495880 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.039720s ]
  12. SELECT * FROM `article` WHERE `id` > 495880 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.055234s ]
  13. SELECT * FROM `article` WHERE `id` < 495880 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.175628s ]
  14. SELECT * FROM `article` WHERE `id` < 495880 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.122713s ]
  15. SELECT * FROM `article` WHERE `id` < 495880 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.125478s ]
0.741574s