Linux进程控制

简介: 进程控制1. fork后内核做什么?分配新的内存块和内核数据结构给子进程将父进程部分数据结构拷贝子进程将子进程添加到系统进程列表中fork返回开始调度器调度2. fork调用失败的原因系统中有太多的进程实际用户的进程数超过了上限3. 进程退出场景代码运行完毕,结果正确代码运行完毕,结果不正确代码异常终止4. 查看进程退出码echo $? 只会保留最近一次执行的进程的退出码

1. fork后内核做什么?

  1. 分配新的内存块和内核数据结构给子进程
  2. 将父进程部分数据结构拷贝子进程
  3. 将子进程添加到系统进程列表中
  4. fork返回开始调度器调度

2. fork调用失败的原因

  1. 系统中有太多的进程
  2. 实际用户的进程数超过了上限

3. 进程退出场景

  1. 代码运行完毕,结果正确
  2. 代码运行完毕,结果不正确
  3. 代码异常终止

4. 查看进程退出码

echo $? 只会保留最近一次执行的进程的退出码

5. 进程退出常用方法

  1. main函数中return返回
  2. 调用exit()函数
  3. 调用_exit()函数

6. exit()函数和_exit()函数的区别

  1. exit()函数执行用户定义的清理函数
  2. 关闭所有打开的流,所有缓存器均被写入
  3. 调用_exit()函数

7. 进程的等待必要性

  1. 僵尸进程可能会造成内存泄漏
  2. 回收子进程资源,获取子进程退出信息

8. 进程等待方法

wait()函数方法:成功返回等待进程PID,失败则返回-1;参数不关心则可以设置NULL

waitpid()函数方法:成功返回子进程PID,如果设置了WNOHANG,而调用中waitpid已经收集返回0,调用出错返回-1;参数:PID=-1等待任一一个子进程,PID>0等待其进程PID与子进程相等的PID;status: WIFEXITED:查看进程是否退出,WEXITSTATUS:查看进程退出码:options:若指定PID的子进程没结束,返回0;结束返回子进程PID

status:是int*类型,指向的是一个int大小的空间,32个比特位,其中从右向左数,第7-15这八个比特位是退出状态,第0-6这7个比特位是终止信号,第7这个比特位是core dump标志位


怎么获取进程的退出码和终止信号呢?

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/types.h>    
#include <sys/wait.h>    
int main()    
{    
  pid_t id = fork();    
  if(id == 0)    
  {    
    //子进程    
    int count = 0;    
    while(1)    
    {    
      if(count == 5)    
      {    
        break;    
      }    
      printf("我是子进程,PID:%d,PPPID:%d\n", getpid(), getppid());    
      count++;                                                                                                                                                 
      sleep(1);    
    }    
    exit(2);    
  }    
  //父进程    
  int status = 0;    
  pid_t father_id = waitpid(id, &status, 0);    
  printf("我是父进程,PID:%d,PPID:%d,father_id:%d,子进程退出码:%d,子进程终止信号:%d\n", \    
      getpid(), getppid(), father_id, (status >> 8) & 0xFF, status & 0x7F);    
  return 0;    
}  

父进程在wait的时候,如果子进程没有退出,父进程是在干什么呢?

在子进程没有的时候,父进程只有一直在调用waitpid进程等待,这种等待就是阻塞等待。

如果父进程不想在waitpid处卡住呢,而是去做做别的事情呢,这时怎么来解决这个问题?

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/types.h>    
#include <sys/wait.h>    
int main()    
{    
  pid_t id = fork();    
  if(id == 0)    
  {    
    //子进程    
    int count = 0;    
    while(1)    
    {    
      if(count == 5)    
      {    
        break;    
      }    
      printf("我是子进程,PID:%d,PPPID:%d\n", getpid(), getppid());    
      count++;    
      sleep(1);    
    }    
    exit(2);    
  }    
  //父进程    
  while(1)    
  {    
    int status = 0;    
    pid_t father_id = waitpid(id, &status, WNOHANG);    
    if(father_id < 0)    
    {    
      printf("err\n");    
      exit(-1);    
    }    
    else if(father_id == 0)                                                                                 
    {    
      printf("子进程没有退出\n");    
      sleep(1);    
      continue;    
    }    
    else    
    {    
      printf("我是父进程,PID:%d,PPID:%d,father_id:%d,子进程退出码:%d,子进程终止信号:%d\n", \    
          getpid(), getppid(), father_id, (status >> 8) & 0xFF, status & 0x7F);    
      break;    
    }    
    return 0;    
  }    
}    

也可以用宏来获取退出码

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    
#include <sys/types.h>    
#include <sys/wait.h>    
int main()    
{    
  pid_t id = fork();    
  if(id == 0)    
  {    
    //子进程    
    int count = 0;    
    while(1)    
    {    
      if(count == 5)    
      {    
        break;    
      }    
      printf("我是子进程,PID:%d,PPPID:%d\n", getpid(), getppid());    
      count++;    
      sleep(1);    
    }    
    exit(2);    
  }    
  //父进程    
  while(1)    
  {    
    int status = 0;    
    pid_t father_id = waitpid(id, &status, WNOHANG);    
    if(father_id < 0)    
    {    
      printf("err\n");    
      exit(-1);    
    }    
    else if(father_id == 0)                                                                                 
    {    
      printf("子进程没有退出\n");    
      sleep(1);    
      continue;    
    }    
    else    
    {    
       if(WIFEXITED(status)) //收到信号
       {
          printf("等待成功,退出码是:%d\n", WEXITSTATUS(status));
       }
       else
       {
        printf("等待成功,信号是:%d\n", status & 0x7F);
       }
      break;    
    }    
    return 0;    
  }    
}  

9. 进程程序替换

9.1 现象

[jyh@VM-12-12-centos study8]$ ll
total 24
-rw-rw-r-- 1 jyh jyh  152 Mar  7 16:55 Makefile
-rw-rw-r-- 1 jyh jyh 2045 Mar  7 16:43 proc.c
-rwxrwxr-x 1 jyh jyh 8416 Mar  7 16:56 procReplace
-rw-rw-r-- 1 jyh jyh  271 Mar  7 16:56 procReplace.c
[jyh@VM-12-12-centos study8]$ cat procReplace.c
#include <stdio.h>
#include <unistd.h>
int main()
{
  printf("begin......\n");
  printf("begin......\n");
  printf("begin......\n");
  execl("/bin/ls", "ls", "-a", "-l", NULL);
  printf("end.....\n");
  printf("end.....\n");
  printf("end.....\n");
  return 0;
}
[jyh@VM-12-12-centos study8]$ ./procReplace 
begin......
begin......
begin......
total 32
drwxrwxr-x  2 jyh jyh 4096 Mar  7 16:56 .
drwxrwxr-x 15 jyh jyh 4096 Mar  7 15:42 ..
-rw-rw-r--  1 jyh jyh  152 Mar  7 16:55 Makefile
-rw-rw-r--  1 jyh jyh 2045 Mar  7 16:43 proc.c
-rwxrwxr-x  1 jyh jyh 8416 Mar  7 16:56 procReplace
-rw-rw-r--  1 jyh jyh  271 Mar  7 16:56 procReplace.c

我们发现上述代码中执行procReplace.c这个进程的时候,然后调用execl来执行另外一个程序时,procRepalce.c进程被替换了,并没有执行完execl再来执行procReplace.c程序,这就是程序替换。

9.2 原理

进程有对应的PCB,最后数据和代码别加载到内存中,调用execl函数时,该进程的代码和数据完全被新程序替换,执行新程序。进程的程序替换并没有创建新的进程,调用execl函数前后该进程的PID并没有变化。

[jyh@VM-12-12-centos study8]$ ll
total 24
-rw-rw-r-- 1 jyh jyh  152 Mar  7 16:55 Makefile
-rw-rw-r-- 1 jyh jyh 2045 Mar  7 16:43 proc.c
-rwxrwxr-x 1 jyh jyh 8624 Mar  7 17:21 procReplace
-rw-rw-r-- 1 jyh jyh  578 Mar  7 17:21 procReplace.c
[jyh@VM-12-12-centos study8]$ cat procReplace.c
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
  pid_t id = fork();
  if(id == 0)
  {
    printf("我是子进程,我的PID:%d\n", getpid());
    execl("/bin/ls","ls", "-a", "-l");
  }
  sleep(5);
  printf("我是父进程,我的PID:%d\n", getpid());
  waitpid(id, NULL, 0);
  return 0;
}
[jyh@VM-12-12-centos study8]$ ./procReplace 
我是子进程,我的PID:8085
total 32
drwxrwxr-x  2 jyh jyh 4096 Mar  7 17:21 .
drwxrwxr-x 15 jyh jyh 4096 Mar  7 15:42 ..
-rw-rw-r--  1 jyh jyh  152 Mar  7 16:55 Makefile
-rw-rw-r--  1 jyh jyh 2045 Mar  7 16:43 proc.c
-rwxrwxr-x  1 jyh jyh 8624 Mar  7 17:21 procReplace
-rw-rw-r--  1 jyh jyh  578 Mar  7 17:21 procReplace.c
我是父进程,我的PID:8084
[jyh@VM-12-12-centos study8]$ 

上述观察到:子进程中调用execl函数并不会影响父进程,说明操作系统在调用execl时对代码和数据完成了写时拷贝。这里的写时拷贝是拷贝的代码,说明写时拷贝可以发生在代码区。

9.3 接口

  1. execl
int execl(const char* path, const char* arg, ...);
//path:路径
//arg:参数
//最后参数列表必须以NULL结尾

实例

#include <stdio.h>
#include <unistd.h>
int main()
{
  execl("/bin/pwd", "pwd", NULL);
  return 0;
}
  1. execv
int execv(const char* path, char* const argv[]);
//path:路径
//argv:字符串数组
//argv[]中必须以NULL结尾

实例

#include <stdio.h>
#include <unistd.h>
int main()
{
  char* const argv[] = {"ls", "-a", "-l", NULL};
  execv("/bin/ls", argv);
  return 0;
}
  1. execlp
int execlp(const char* file, const char* arg, ...);
//file:文件
//arg:参数
//参数列表必须以NULL结尾
//作用:系统自动在环境变量PATH中进行查找file按照参数执行

实例

#include <stdio.h>
#include <unistd.h>
int main()
{
  execlp("ls", "ls", "-a", "-l", NULL);
  return 0;
}
//这里的两个ls不一样,第一个ls是执行文件名,第二个ls及以后是怎样执行的参数
  1. execvp
int execvp(const char* file, char* const argv[], ...);

实例

[jyh@VM-12-12-centos study9]$ tree
.
|-- exec
|   |-- Makefile
|   |-- otherTest
|   `-- otherTest.cc
|-- Makefile
|-- mytest
`-- test.c
1 directory, 6 files
[jyh@VM-12-12-centos study9]$ cat test.c
#include <stdio.h>
#include <unistd.h>
int main()
{
  char* const myenv[] = {"MYENV=study9/test.c", NULL};
  execle("./exec/otherTest", "otherTest", NULL, myenv);
  return 0;
}
[jyh@VM-12-12-centos study9]$ cat ./exec/otherTest.cc
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main()
{
  for(int i = 0; i < 3; ++i)
  {
    cout << "我是exec路径下的程序,我的PID是: " << getpid() << " " << "MYENV:"<< (getenv("MYENV") == NULL ? "NULL" : getenv("MYENV")) << endl;
    sleep(1);
  }
  return 0;
}
[jyh@VM-12-12-centos study9]$ cat Makefile 
mytest:test.c
  gcc -o $@ $^
.PHONY:clean
clean:
  rm -f mytest
[jyh@VM-12-12-centos study9]$ cat ./exec/Makefile 
otherTest:otherTest.cc
  g++ -o $@ $^
.PHONY:clean
clean:
  rm -f otherTest
[jyh@VM-12-12-centos study9]$ ./mytest 
我是exec路径下的程序,我的PID是: 6359 MYENV:study9/test.c
我是exec路径下的程序,我的PID是: 6359 MYENV:study9/test.c
我是exec路径下的程序,我的PID是: 6359 MYENV:study9/test.c
[jyh@VM-12-12-centos study9]$ 

这里就可以掌握使用了。但是看下面的问题:

[jyh@VM-12-12-centos study9]$ clear
[jyh@VM-12-12-centos study9]$ tree
.
|-- exec
|   |-- Makefile
|   |-- otherTest
|   `-- otherTest.cc
|-- Makefile
|-- mytest
`-- test.c
1 directory, 6 files
[jyh@VM-12-12-centos study9]$ cd exec/
[jyh@VM-12-12-centos exec]$ cat otherTest.cc 
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main()
{
  for(int i = 0; i < 3; ++i)
  {
    cout << "------------------------------------------------------" << endl;
    cout << "我是exec路径下的程序,我的PID是: " << getpid() << endl;
    cout << "MYENV:"<< (getenv("MYENV") == NULL ? "NULL" : getenv("MYENV")) << endl;
    cout << "PATH:"<< (getenv("PATH") == NULL ? "NULL" : getenv("PATH")) << endl;
    cout << "------------------------------------------------------" << endl;
    sleep(1);
  }
  return 0;
}
[jyh@VM-12-12-centos exec]$ ./otherTest 
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8867
MYENV:NULL
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8867
MYENV:NULL
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8867
MYENV:NULL
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
[jyh@VM-12-12-centos exec]$ cd ..
[jyh@VM-12-12-centos study9]$ pwd
/home/jyh/linux_-stu/study9
[jyh@VM-12-12-centos study9]$ cat test.c
#include <stdio.h>
#include <unistd.h>
int main()
{
  char* const myenv[] = {"MYENV=study9/test.c", NULL};
  execle("./exec/otherTest", "otherTest", NULL, myenv);
  return 0;
}
[jyh@VM-12-12-centos study9]$ ./mytest 
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8910
MYENV:study9/test.c
PATH:NULL
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8910
MYENV:study9/test.c
PATH:NULL
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 8910
MYENV:study9/test.c
PATH:NULL
------------------------------------------------------[jyh@VM-12-12-centos study9]$ 

现象:当本程序中设定自定义环境变量,另外的程序中有系统环境变量,此时运行本程序时,另外的程序中的系统环境变量为NULL。说明了:自定义环境变量是覆盖式传入,覆盖了系统的环境变量,所以导致这里系统环境变量为NULL。这里怎么解决呢?

int putenv(char* string);
//作用:改变或者添加一个环境变量
[jyh@VM-12-12-centos study9]$ tree
.
|-- exec
|   |-- Makefile
|   |-- otherTest
|   `-- otherTest.cc
|-- Makefile
|-- mytest
`-- test.c
1 directory, 6 files
[jyh@VM-12-12-centos study9]$ cat ./exec/otherTest.cc
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main()
{
  for(int i = 0; i < 3; ++i)
  {
    cout << "------------------------------------------------------" << endl;
    cout << "我是exec路径下的程序,我的PID是: " << getpid() << endl;
    cout << "MYENV:"<< (getenv("MYENV") == NULL ? "NULL" : getenv("MYENV")) << endl;
    cout << "PATH:"<< (getenv("PATH") == NULL ? "NULL" : getenv("PATH")) << endl;
    cout << "------------------------------------------------------" << endl;
    sleep(1);
  }
  return 0;
}
[jyh@VM-12-12-centos study9]$ cat test.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
  extern char** environ;
  char* const myenv[] = {"MYENV=study9/test.c", NULL};
  putenv("MYENV=study9/test.c"); 
  execle("./exec/otherTest", "otherTest", NULL, environ);
  return 0;
}
[jyh@VM-12-12-centos study9]$ ./mytest 
------------------------------------------------------
我是exec路径下的程序,我的PID是: 14363
MYENV:study9/test.c
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 14363
MYENV:study9/test.c
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
------------------------------------------------------
我是exec路径下的程序,我的PID是: 14363
MYENV:study9/test.c
PATH:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jyh/.local/bin:/home/jyh/bin
------------------------------------------------------
[jyh@VM-12-12-centos study9]$ 

这里考虑一个问题:环境变量具有全局属性,可以被子进程继承下去,这里怎么做到的呢?


因为所有的指令都是bash的子进程,而bash执行指令都可以使用execl来执行,我们要把bash的环境变量交给子进程,子进程只是需要调用execle,再把对应的bash的环境变量作为参数即可被子进程继承下去。

  1. execvpe
int execvpe(const char* file, char* const argv[], char* const envp[]);
  1. execve
int execve(const char* filename, char* const argv[], char* const envp[]);

10. 编写极简shell

[jyh@VM-12-12-centos demo]$ ll
total 8
-rw-rw-r-- 1 jyh jyh   74 Mar  8 17:10 Makefile
-rw-rw-r-- 1 jyh jyh 1716 Mar  8 17:31 mybash.c
[jyh@VM-12-12-centos demo]$ cat mybash.c 
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/wait.h>
#include <sys/types.h>
//模拟实现极简bash命令行
#define COMMANDMAXSIZE 1024
#define ARGVMAXSIZE 64
int split(char* command_string, char* argv[])
{
  assert(command_string != NULL && argv != NULL);
  argv[0] = strtok(command_string, " ");
  if(argv[0] == NULL) 
  {
    return -1;
  }
  int i = 1;
  while((argv[i++] = strtok(NULL, " ")));
  //while(1)
  //{
  //  argv[i] = strtok(NULL, " ");
  //  if(argv[i] == NULL)
  //  {
  //    break;
  //  }
  //  ++i;
  //}
  return 0;
}
void debugOut(char* argv[])
{
  int i = 0;
  while(argv[i] != NULL)
  {
    printf("%d->%s\n", i, argv[i]);
    ++i;
  }
  //for(int i = 0; argv[i] != NULL; ++i)
  //{
  //  printf("%d->%s\n", i, argv[i]);
  //}
}
int main()
{
  while(1)
  {
    char command_string[COMMANDMAXSIZE] = {0};
    printf("[name@my_root currrent_path]# ");
    fflush(stdout);
    char* s = fgets(command_string, sizeof(command_string), stdin);
    assert(s != NULL);
    (void)s; //保证release版本时,因为去掉assert()导致ret未被使用,而带来的编译告警
    command_string[strlen(command_string) - 1] = '\0'; //去掉回车导致的换行
    char* argv[ARGVMAXSIZE] = {NULL};
    int ret = split(command_string, argv); //命令字符串切割
    if(ret != 0)
    {
      continue;
    }
    //debugOut(argv);
    pid_t id = fork();
    assert(id >= 0);
    if(id == 0) //子进程
    {
      execvp(argv[0], argv);
      exit(0); 
    }
    //父进程
    int status = 0;
    waitpid(id, &status, 0);
    //子进程去执行对应的命令,父进程等待子进程
  }
  return 0;
}
[jyh@VM-12-12-centos demo]$ cat Makefile 
mybash:mybash.c
  gcc -o $@ $^ -std=c99
.PHONY:clean
clean:
  rm -f mybash
[jyh@VM-12-12-centos demo]$ 
































目录
打赏
0
0
0
0
0
分享
相关文章
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
128 1
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
69 34
|
4天前
|
Linux:守护进程(进程组、会话和守护进程)
守护进程在 Linux 系统中扮演着重要角色,通过后台执行关键任务和服务,确保系统的稳定运行。理解进程组和会话的概念,是正确创建和管理守护进程的基础。使用现代的 `systemd` 或传统的 `init.d` 方法,可以有效地管理守护进程,提升系统的可靠性和可维护性。希望本文能帮助读者深入理解并掌握 Linux 守护进程的相关知识。
21 7
|
3天前
|
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
28 5
Linux 进程管理基础
Linux 进程是操作系统中运行程序的实例,彼此隔离以确保安全性和稳定性。常用命令查看和管理进程:`ps` 显示当前终端会话相关进程;`ps aux` 和 `ps -ef` 显示所有进程信息;`ps -u username` 查看特定用户进程;`ps -e | grep &lt;进程名&gt;` 查找特定进程;`ps -p &lt;PID&gt;` 查看指定 PID 的进程详情。终止进程可用 `kill &lt;PID&gt;` 或 `pkill &lt;进程名&gt;`,强制终止加 `-9` 选项。
15 3
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
61 16
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
168 20
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
540 58
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
133 13
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等