找回密码
 立即注册
首页 业界区 业界 重生之我是操作系统(三)----进程&线程 ...

重生之我是操作系统(三)----进程&线程

刃减胸 2025-6-2 00:38:42
简介

进程是系统资源分配的最小单位,它曾经也是CPU调度的最小单位,但后面被线程所取代。
进程树

Linux系统通过父子进程关系串联起来,所有进程之前构成了一个多叉树结构。
1.png

孤儿进程

孤儿进程是指父进程已经结束,子进程还在执行的进程。那么此时此刻,该进程就变成了孤儿进程。
当进程变成孤儿进程后,系统会认领该进程,并为他再分配一个父进程(就近原则,爸爸的爸爸,爸爸的爸爸的爸爸)。
》当孤儿进程被认领后,就很难再进行标准输入输出对其控制了。因为切断了跟终端的联系,所以编码过程中要尽量避免出现孤儿进程
进程通讯(inter -Process Communication,IPC)

多个进程之间的内存相互隔离,多个进程之间通讯方式有如下几种:
管道(pipe)

2.png

匿名管道

半双工通信,即数据只能在一个方向上流动。只能在具有父子关系的进程之间使用。
其原理为:内核在内存中创建一个缓冲区,写入端将数据写入缓冲区,读取端从缓冲区中读取数据
点击查看代码
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. int main() {
  5.     int pipefd[2];
  6.     pid_t pid;
  7.     char buffer[100];
  8.     // 创建管道
  9.     if (pipe(pipefd) == -1) {
  10.         perror("pipe");
  11.         return 1;
  12.     }
  13.     // 创建子进程
  14.     pid = fork();
  15.     if (pid == -1) {
  16.         perror("fork");
  17.         return 1;
  18.     }
  19.     if (pid == 0) {
  20.         // 子进程:关闭写端,从管道读取数据
  21.         close(pipefd[1]);
  22.         read(pipefd[0], buffer, sizeof(buffer));
  23.         printf("Child process received: %s\n", buffer);
  24.         close(pipefd[0]);
  25.     } else {
  26.         // 父进程:关闭读端,向管道写入数据
  27.         close(pipefd[0]);
  28.         const char *message = "Hello, child process!";
  29.         write(pipefd[1], message, strlen(message) + 1);
  30.         close(pipefd[1]);
  31.     }
  32.     return 0;
  33. }
复制代码
命名管道

可以在任意两个进程之间进行通信,不要求进程具有亲缘关系;遵循先进先出(FIFO)原则。
其原理为:在文件系统中创建一个特殊的文件,进程通过读写这个文件来进行通信,因此文件读取是从头开始读,先进先出。
点击查看代码
  1. // 写进程
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #define FIFO_NAME "myfifo"
  7. int main() {
  8.     int fd;
  9.     const char *message = "Hello, named pipe!";
  10.     // 创建命名管道
  11.     mkfifo(FIFO_NAME, 0666);
  12.     // 打开命名管道进行写操作
  13.     fd = open(FIFO_NAME, O_WRONLY);
  14.     if (fd == -1) {
  15.         perror("open");
  16.         return 1;
  17.     }
  18.     // 向命名管道写入数据
  19.     write(fd, message, strlen(message) + 1);
  20.     close(fd);
  21.     return 0;
  22. }
  23. // 读进程
  24. #include <stdio.h>
  25. #include <fcntl.h>
  26. #include <unistd.h>
  27. #define FIFO_NAME "myfifo"
  28. int main() {
  29.     int fd;
  30.     char buffer[100];
  31.     // 打开命名管道进行读操作
  32.     fd = open(FIFO_NAME, O_RDONLY);
  33.     if (fd == -1) {
  34.         perror("open");
  35.         return 1;
  36.     }
  37.     // 从命名管道读取数据
  38.     read(fd, buffer, sizeof(buffer));
  39.     printf("Received: %s\n", buffer);
  40.     close(fd);
  41.     // 删除命名管道
  42.         // 理论上,命名管道是可以重复使用的,其本质就是操作文件而已。只是不建议这么操作。
  43.     unlink(FIFO_NAME);
  44.     return 0;
  45. }
复制代码
共享内存(Shared Memory)

多个进程共享同一块内存地址,是最快的IPC方式。
其原理为:内核在物理内存中分配一块内存区域,多个进程将内存地址映射到自己的虚拟空间内,从而可以直接读写该区域。
3.png

点击查看代码[code]#include #include #include #include #include #include #include int main(int argc, char const *argv[]){    //创建一个共享内存对象    char shm_name[100]={0};    sprintf(shm_name,"/letter%d",getpid());    int fd= shm_open(shm_name,O_RDWR|O_CREAT,0664);    if(fd

相关推荐

您需要登录后才可以回帖 登录 | 立即注册