Linux 系统编程 进程篇 (五)

进程基础概念

在Linux系统中,进程是程序执行的实例,每个进程拥有独立的地址空间、资源和执行状态。内核通过进程描述符(task_struct结构体)管理进程信息。

进程标识符(PID)是唯一标识进程的数字,父进程标识符(PPID)表示创建该进程的父进程。通过getpid()和getppid()系统调用可获取当前进程的PID和PPID。

进程创建与终止

进程创建

通过fork()系统调用创建子进程,子进程复制父进程的代码段、数据段和堆栈。fork()返回两次:

  • 父进程中返回子进程PID
  • 子进程中返回0
c 复制代码
#include <unistd.h>
pid_t fork(void);

进程终止

正常终止方式包括:

  • 调用exit()或_exit()函数
  • 从main()函数返回
  • 接收到终止信号

exit()会执行标准I/O清理和退出处理程序,而_exit()直接终止进程。

进程间通信(IPC)

管道(Pipe)

匿名管道用于父子进程通信,通过pipe()创建:

c 复制代码
int pipe(int fd[2]);

共享内存

通过shmget()创建共享内存段,shmat()附加到进程地址空间:

c 复制代码
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);

信号(Signal)

使用kill()发送信号,signal()或sigaction()设置信号处理程序:

c 复制代码
int kill(pid_t pid, int sig);
void (*signal(int sig, void (*func)(int)))(int);

进程状态管理

进程状态

Linux进程主要状态包括:

  • 运行(TASK_RUNNING)
  • 可中断等待(TASK_INTERRUPTIBLE)
  • 不可中断等待(TASK_UNINTERRUPTIBLE)
  • 停止(TASK_STOPPED)
  • 僵尸(TASK_ZOMBIE)

进程调度

通过nice()调整进程优先级,sched_setscheduler()设置调度策略:

c 复制代码
int nice(int inc);
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);

守护进程

守护进程是在后台运行的独立进程,创建步骤包括:

  1. 调用fork()创建子进程,父进程退出
  2. 调用setsid()创建新会话
  3. 改变工作目录到根目录
  4. 重设文件权限掩码
  5. 关闭继承的文件描述符
c 复制代码
pid_t pid = fork();
if (pid > 0) exit(0);
setsid();
chdir("/");
umask(0);
for (int i = 0; i < sysconf(_SC_OPEN_MAX); i++) close(i);

进程监控

进程列表

通过ps命令查看进程信息,或编程方式读取/proc文件系统:

c 复制代码
DIR *dir = opendir("/proc");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    if (isdigit(entry->d_name[0])) {
        printf("PID: %s\n", entry->d_name);
    }
}
closedir(dir);

进程资源
getrusage()获取进程资源使用情况:

c 复制代码
int getrusage(int who, struct rusage *usage);
相关推荐
极光通讯2 分钟前
服务器内存替代料选型方法论:主料号缺货时如何找到Pin-to-Pin兼容型号
运维·服务器
Raas1003 分钟前
AI网关能做语义缓存吗?MAI Gateway(魔芋企业级AI网关)实战能力深度解读
java·后端·spring
天空鸟_时光不老10 分钟前
13-亮点提炼:把技术说辞翻译成业务价值
java·spring boot·spring·spring cloud·mybatis
小蒜学长14 分钟前
基于SpringBoot+Vue的租房管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·租房管理
C++ 老炮儿的技术栈16 分钟前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c
人生百态,人生如梦17 分钟前
Ubuntu在低版本下使用ccswitch+claudecode(CCSwitch+Docker+Claude)连调教程
linux·ubuntu·docker·claudecode·ccswitch
洋就在江州20 分钟前
gitlab-cicd 离线集成——springboot-cicd (非docker形式,shell形式)
java·spring boot·后端·ci/cd·gitlab·gitlab-runner
CEZ27 分钟前
JeeWMS 开源 WMS 全景导览:一套 Java 仓库管理系统从单据流到代码入口的阅读地图
java·开源
Nebula_g27 分钟前
JavaSE加强:线程Thread(线程安全重点)
java·开发语言·jvm·算法·javase·技术栈
令狐少侠201132 分钟前
centos7 下,使用docker 部署IOT 调试平台,ThingsBoard 并完美启动
java·spring boot·iot