Linux进程基础知识

1. 什么是进程?

  • 进程就是运行中的程序,是系统资源分配的基本单位
  • 每个进程都有唯一的PID(进程ID)
  • 进程有父子关系,通过ps -ef可以查看

2. 进程的创建 - fork()

复制代码
pid_t pid = fork();
  • 简单理解:fork()就像细胞分裂,一个变两个
  • 调用一次,返回两次:父进程得到子进程PID,子进程得到0
  • 子进程是父进程的复制品

3. 进程的程序替换 - exec族

复制代码
execl("/bin/ls", "ls", "-l", NULL);
  • 保留进程ID,但内容完全变成新程序
  • 就像换灵魂:外壳不变,内在全变
  • 常用函数:execl, execlp, execle, execv, execvp等

4. 进程的等待与回收 - wait/waitpid

复制代码
pid_t wait(int *status);

pid_t waitpid(pid_t pid, int *status, int options);
  • 父进程等待子进程结束并回收资源
  • 避免僵尸进程(zombie)的产生
  • waitpid比wait更灵活,可以非阻塞等待

5. 进程的退出

exit(0); // 标准C库函数

_exit(0); // 系统调用

  • exit会刷新缓冲区,exit直接退出
  • 返回值0表示正常退出

一. 文件操作与I/O

1. 文件描述符

  • 就像文件的"身份证号码"
  • 标准输入(0)、标准输出(1)、标准错误(2)
  • 每个进程最多可打开的文件数有限制

2. 文件操作基本函数

复制代码
// 打开文件

int fd = open("test.txt", O_RDWR | O_CREAT, 0644);

// 读取文件

char buf[1024];

int n = read(fd, buf, sizeof(buf));

// 写入文件

write(fd, "hello", 5);

// 关闭文件

close(fd);

// 文件指针定位

lseek(fd, 0, SEEK_SET);  // 回到文件开头

3. 文件属性获取

复制代码
struct stat st;

stat("file.txt", &st);



- 获取文件大小:st.st_size
  • 判断文件类型:S_ISREG(st.st_mode)、S_ISDIR(st.st_mode)

4. 目录操作

复制代码
DIR *dir = opendir(".");

struct dirent *entry;

while ((entry = readdir(dir)) != NULL) {

    printf("%s\n", entry->d_name);

}

closedir(dir);

三、进程间通信(IPC)

1. 管道通信

复制代码
int fd[2];

pipe(fd);  // fd[0]读端,fd[1]写端
  • 单向通信:水管模型,一端进一端出
  • 只能用于有亲缘关系的进程
  • 适合简单的数据传输

2. 命名管道(FIFO)

复制代码
// 创建命名管道

mkfifo("myfifo", 0644);

// 使用方法与普通文件类似

int fd = open("myfifo", O_WRONLY);
  • 可用于无关进程间通信
  • 遵循先进先出原则

3. 信号通信

复制代码
// 信号处理函数

void sig_handler(int signo) {

    printf("收到信号: %d\n", signo);

}

// 设置信号处理

signal(SIGINT, sig_handler);
  • 常见信号:
  • SIGINT (2): Ctrl+C中断
  • SIGKILL (9): 强制终止(不可捕获)
  • SIGTERM (15): 终止信号
  • SIGCHLD (17): 子进程状态改变
  • SIGALRM (14): 定时器到期

四、实用示例

1. 创建守护进程

复制代码
void daemonize() {

    pid_t pid = fork();

    if (pid < 0) exit(1);

    if (pid > 0) exit(0);  // 父进程退出

    

    setsid();  // 创建新会话

    

    // 关闭标准输入输出错误

    close(0);

    close(1);

    close(2);

    // ...更多操作

}

2. 简单shell实现

复制代码
while (1) {

    printf("myshell> ");

    fgets(cmd, sizeof(cmd), stdin);

    

    if (fork() == 0) {

        // 子进程执行命令

        execlp(cmd, cmd, NULL);

        exit(0);

    } else {

        // 父进程等待

        wait(NULL);

    }

}

五、常见错误与调试技巧

1. 经典错误

  • 僵尸进程:子进程结束但未被回收
  • 孤儿进程:父进程先于子进程结束
  • 内存泄漏:申请的内存未释放
  • 文件描述符泄漏:打开文件未关闭

2. 调试工具

  • strace:跟踪系统调用
  • gdb:代码调试器
  • valgrind:内存错误检测
  • lsof:查看打开的文件
相关推荐
随猿Fa38 分钟前
用密钥方式让通过JumpServer代理的服务器可以在我本地电脑直接访问
运维·服务器
派阿喵搞电子44 分钟前
Ubuntu 常用命令行指令
linux·ubuntu
库库林_沙琪马1 小时前
Linux 命令全解析:从零开始掌握 Linux 命令行
linux·运维·服务器
嘿rasa1 小时前
2025最新系统 Linux 教程(二)
linux·运维·服务器
浪淘沙jkp1 小时前
AI大模型学习十:‌Ubuntu 22.04.5 调整根目录大小,解决根目录磁盘不够问题
linux·学习·ubuntu
啊吧怪不啊吧2 小时前
Linux常见指令介绍上(入门级)
linux·运维·服务器
菜狗想要变强2 小时前
RVOS-7.实现抢占式多任务
linux·c语言·驱动开发·单片机·嵌入式硬件·risc-v
网络之路Blog2 小时前
【实战中提升自己】 防火墙完结篇之VPX部署–IPSEC VPX,包括与L2TP共存问题
服务器·网络·网络之路一天·华为华三数通基础·华为华三网络基础·数通基础·华为华三数通
ALex_zry2 小时前
从源码到实战:深度解析`rsync`增量同步机制与高级应用
linux·网络·运维开发
栩栩云生2 小时前
📥 x-cmd install | Toolong - 终端日志分析的瑞士军刀
运维·python·数据分析