重生之我是操作系统(三)----进程&线程
简介进程是系统资源分配的最小单位,它曾经也是CPU调度的最小单位,但后面被线程所取代。
进程树
Linux系统通过父子进程关系串联起来,所有进程之前构成了一个多叉树结构。
孤儿进程
孤儿进程是指父进程已经结束,子进程还在执行的进程。那么此时此刻,该进程就变成了孤儿进程。
当进程变成孤儿进程后,系统会认领该进程,并为他再分配一个父进程(就近原则,爸爸的爸爸,爸爸的爸爸的爸爸)。
》当孤儿进程被认领后,就很难再进行标准输入输出对其控制了。因为切断了跟终端的联系,所以编码过程中要尽量避免出现孤儿进程
进程通讯(inter -Process Communication,IPC)
多个进程之间的内存相互隔离,多个进程之间通讯方式有如下几种:
管道(pipe)
匿名管道
半双工通信,即数据只能在一个方向上流动。只能在具有父子关系的进程之间使用。
其原理为:内核在内存中创建一个缓冲区,写入端将数据写入缓冲区,读取端从缓冲区中读取数据
点击查看代码#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
int pipefd;
pid_t pid;
char buffer;
// 创建管道
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) {
// 子进程:关闭写端,从管道读取数据
close(pipefd);
read(pipefd, buffer, sizeof(buffer));
printf("Child process received: %s\n", buffer);
close(pipefd);
} else {
// 父进程:关闭读端,向管道写入数据
close(pipefd);
const char *message = "Hello, child process!";
write(pipefd, message, strlen(message) + 1);
close(pipefd);
}
return 0;
}命名管道
可以在任意两个进程之间进行通信,不要求进程具有亲缘关系;遵循先进先出(FIFO)原则。
其原理为:在文件系统中创建一个特殊的文件,进程通过读写这个文件来进行通信,因此文件读取是从头开始读,先进先出。
点击查看代码// 写进程
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define FIFO_NAME "myfifo"
int main() {
int fd;
const char *message = "Hello, named pipe!";
// 创建命名管道
mkfifo(FIFO_NAME, 0666);
// 打开命名管道进行写操作
fd = open(FIFO_NAME, O_WRONLY);
if (fd == -1) {
perror("open");
return 1;
}
// 向命名管道写入数据
write(fd, message, strlen(message) + 1);
close(fd);
return 0;
}
// 读进程
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define FIFO_NAME "myfifo"
int main() {
int fd;
char buffer;
// 打开命名管道进行读操作
fd = open(FIFO_NAME, O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
// 从命名管道读取数据
read(fd, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
close(fd);
// 删除命名管道
// 理论上,命名管道是可以重复使用的,其本质就是操作文件而已。只是不建议这么操作。
unlink(FIFO_NAME);
return 0;
}共享内存(Shared Memory)
多个进程共享同一块内存地址,是最快的IPC方式。
其原理为:内核在物理内存中分配一块内存区域,多个进程将内存地址映射到自己的虚拟空间内,从而可以直接读写该区域。
点击查看代码#include #include #include #include #include #include #include int main(int argc, char const *argv[]){ //创建一个共享内存对象 char shm_name={0}; sprintf(shm_name,"/letter%d",getpid()); int fd= shm_open(shm_name,O_RDWR|O_CREAT,0664); if(fd
页:
[1]